Difference between func(_) and func _

368 views Asked by At

Anyone can tell me the difference between func _ and func(_) in Scala? I had to override this method:

def validations: List[ValueType => List[FieldError]] = Nil

If I override it with:

val email = new EmailField(this, 255){
  override def validations = valUnique _ :: Nil
  private def valUnique(email: String): List[FieldError] = {
    Nil
  }
}

It is ok, while if I override it with:

val email = new EmailField(this, 255){
  override def validations = valUnique(_) :: Nil
  private def valUnique(email: String): List[FieldError] = {
    Nil
  }
}

It is not ok. Anyone can me explain why? Thank you very much.

2

There are 2 answers

0
Daniel C. Sobral On BEST ANSWER

If you wrote it like this:

override def validations: List[ValueType => List[FieldError]] = valUnique(_) :: Nil

I'm sure it would tell you you are getting a String => List[List[FieldError]] instead of the required type. When an underline is used in place of a parameter (instead of as part of an expression), it is expanded as a function in the immediate outer scope. Specifically,

valUnique(_) :: Nil  // is translated into
x => valUnique(x) :: Nil

(valUnique(_)) :: Nil  // would be translated into
(x => valUnique(x)) :: Nil  // which would be correct

On the other hand, valUnique _ is just saying "get this method and turn it into a function`, so

valUnique _ :: Nil  // gets translated into
(x => valUnique(x)) :: Nil
0
Kevin Wright On

In the case of:

valUnique _

You are partially applying the valUnique method, causing it to be boxed as a function.

On the other hand:

valUnique(_)

specifies a placeholder for a call to the valUnique method, which would typically be done in order to pass an anonymous function to some other high order function, as in:

emails flatMap { valUnique(_) }

In your case, there's nothing in scope that could be used to fulfill such a placeholder, though partial application is still completely valid.

Note that you can also lift a method to a function, before passing it as an argument:

emails flatMap { valUnique _ }

This similarity is almost certainly the cause of your confusion, even though these two forms aren't doing quite the same thing behind the scenes.