Yes, through a mechanism called eta-expansion.
Great, I was reading it before sending it and it sounded quite provocative.
Not really, since methods are more powerful than functions, see the links in the related FAQ entry.
However, the ability to say something like:
def doubleMap[A](data: List[A])(f: A => A): List[A] =
data.map(f).map(f)
Imply that functions are values, they can be passed around, returned and stored on variables.
In any case, you may think that the parameter f
in that method is a val
, so that would be a use case; but I get your point.
There is one reason why you would prefer to have a val
function instead of a method and it is that you are sure that you are going to use it like a function, for example, because you need to call methods on it like andThen
.
For example, imagine you want to provide a method that receives a list of numbers and function from Int to Int, but instead of a normal map
the results will be doubled after (I know, a contrived example but I hope it shows the idea); you could do it like:
object API {
def mapAndDouble(data: List[Int])(f: Int => Int): List[Int]
data.map(f).map(_ * 2)
}
However, mapping twice is quite expensive, it would better to apply both functions at the same time; so you do:
object API {
def mapAndDouble(data: List[Int])(f: Int => Int): List[Int]
data.map(f.andThen(_ * 2))
}
But, for whatever reason, you do not want the _ * 2
function to be created every time, you want to cache it; so you do:
object API {
private val double: Int => Int = i => i * 2
def mapAndDouble(data: List[Int])(f: Int => Int): List[Int]
data.map(f andThen double)
}
Now, again this is very weird and in this case, it is not even clear why you would even want that.
During my 5 years using Scala I have only needed to that once and the snippet is somewhat complex so that is why I tried to come with a simpler example.