Ah okay, I think I understand now what is the confusion.
In Scala, functions are just values, like any other value (for example numbers). Also, in Scala, all values are objects, instances of a class, and members of some types.
Thus, you can call methods on a function itself.
In particular, for this case, we need to look into the type definition of a function of a single argument and a ]function of two arguments:
// The compiler allows us to write this as I1 => O
trait Function1[I1, O] {
// Invoking a function is just calling its apply method.
def apply(i1: I1): O
}
// The compiler allows us to write this as (I1, I2) => O
trait Function2[I1, I2, O] {
// Invoking a function is just calling its apply method.
def apply(i1: I1, i2: I2): O
// Transforms this function of two arguments,
// into one that takes a single tuple argument.
// It delegates to the current logic by unpacking the tuple.
final def tupled: ((I1, I2)) => O =
tuple => this.apply(i1 = tuple._1, i2 = tuple._2)
}
BTW, technically speaking, when you use def
you are creating a METHOD, not a FUNCTION; they are different: Scala FAQ | Scala Documentation (but, in practice, you don’t need to be this pedantic).
However, it is trivial to create a FUNCTION from a METHOD, by delegation:
def aMethod(x: Int): Int = ...
val aFunction: Int => Int = x => aMethod(x)
Since this process is trivial, the compiler can do it automatically for us.
In Scala 2 it sometimes needed some help, like (consumer _)
in @WojciechMazur original example.