These two values have different types:
val literal1: (Int => Int, Int) => Int = <function>
val literal2: (Int => Int) => (Int => Int) = <function>
In other words, literal1
is a function that takes two arguments—a function that takes an Int
and returns an Int
, and an Int
—and returns an Int
.
On the other hand, literal2
is a function that takes one argument—a function that takes an Int
and returns an Int
, and returns a function that takes an Int
and returns an Int
.
Other than the different calling convention, the second form allows you to easily partially apply the first parameter, returning a function that takes an Int
and returns an Int
:
val doubler = literal2(_ * 2) // val doubler: Int => Int = <function>
doubler(2) // val res0: Int = 4
doubler(5) // val res1: Int = 10
Doing the same with the first form requires very slightly more complex syntax:
val doubler = literal1(_ * 2, _)
doubler(2)
doubler(5)
The first form can be transformed automatically to the second using its curried
method:
val literal3 = literal1.curried // val literal3: (Int => Int) => (Int => Int) = scala.Function2<function>
literal3(_ * 3)(6) // val res2: Int = 18
Note that it is conventional in Scala for functions and methods that take a single function argument to specify it as the final argument in a curried format, as this allows for a convenient syntax for a multi-line lambda:
val literal4 = (x: Int) => (fn: Int => Int) => fn(x)
literal4(25) { x =>
val mod = x % 2
if (mod == 0) println("even")
else println("odd")
mod
}
Output:
val literal4: Int => ((Int => Int) => Int) = <function>
odd
val res3: Int = 1