Having a function f defined as:
def f(i1: Int, i2: Int)(i3: Int) = i1 + i2 + i3
It is possible to define a partially applied function as follows using _:
val f12 = f(1, 2) _ // f12: Int => Int = <function>
f12(3) // res0: Int = 6
Now when I return a partially applied function from a function, I do not need to use _:
def f23(f: (Int, Int) => Int => Int) = f(2, 3) // f23: (f: (Int, Int) => Int => Int)Int => Int
val f23f = f23(f) // f23f: Int => Int = <function>
f23f(4) // res1: Int = 9
If I place _ at the f23 definition I will get an Error:
def f23(f: (Int, Int) => Int => Int) = f(2, 3) _
Error:(6, 49) _ must follow method; cannot follow Int => Int
def f23(f: (Int, Int) => Int => Int) = f(2, 3) _
What is the reason for this inconsistency?
fis a method, not a function. You can read about some of the differences here.f12is a function derived fromfvia eta-expansion. It is not a partial function. APartialFunctionis a function defined over a limited domain of input values. If, say,f12was defined only forIntvalues less than 500, for example, and undefined for input values greater than 500, then it would be a partial function.This fails because
f, as defined here, is a function that takes 2Intvalues and returns a function that takes anIntand returns anInt. In this situation what is the underscore supposed to be standing in for?f(2,3)is a complete invocation that returns anInt=>Intfunction. It's a bit like writing5 + 7 _. It's not clear what the_is substituting for.You can, on the other hand, do this:
... = f(2,3)(_). Then it's clear that the returned function is being invoked with a missing, i.e._, parameter. Which is the same thing as:... = f(2,3).