When using the following syntax to define functions with currying enabled:
def sum(x: Int)(y: Int)(z: Int) = x + y + z
one still has to suffix any calls to curried calls of sum
with _
:
sum _
sum(3) _
sum(3)(2) _
otherwise the compiler will complain.
So I resorted to:
val sum = (x: Int) => (y: Int) => (z: Int) => x + y + z
which works without the _
.
Now the question: why does the multiple-parameter-lists version require _
in order for currying to kick in? Why aren't the semantics of those 2 versions equivalent in all contexts?
Also, is the latter version somehow discouraged? Does it suffer from any caveats?
The reason why those two semantics are different, is that methods and functions are not the same thing.
Methods are full-fledges JVM methods, whereas functions are values (i.e. instance of classes like Function1
, Function2
and so on).
So
def sum(x: Int)(y: Int)(z: Int) = x + y + z
and
val sum = (x: Int) => (y: Int) => (z: Int) => x + y + z
may seem identical, but the first is an method, while the second is a Function1[Int, Function1[Int, Function1[Int, Int]]]
When you try to use a method where a function value is expected, the compiler automatically converts it to a function (a process called eta-expansion).
However, there are case in which the compiler doesn't eta-expand the methods automatically, such as the cases you exposed, in which you explicitly want to partially apply it.
Using _
triggers the eta-expansion, so a method is converted to a function, and everybody is happy.
According to the scala specification, you could also annotate the expected type, in which case the expansion is performed automatically:
def sum(x: Int)(y: Int)(z: Int) = x + y + z
val sumFunction: Int => Int => Int => Int = sum
which is the same reason why
def sum(x: Int, y: Int) = x + y
List(1,2,3).reduce(sum)
works, i.e. we're passing a method where a function is explicitly required.
Here's a more in-depth discussion of when scala performs an eta-expansion: https://stackoverflow.com/a/2394063/846273
Concerning the choice of which to adopt, I'll point you to this answer, which is very exhaustive.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With