I\'m following the tutorial Pattern matching & functional composition on Scala compose
and andThen
methods. There\'s such an example:
From compose
documentation:
Composes two instances of Function1 in a new Function1, with this function applied last.
so you should write
scala> val ummThenAhem = (addAhem _).compose(addUmm _)
ummThenAhem: String => java.lang.String = <function1>
to treat addAhem
and addUmm
as partially applied functions (i.e function1
)
scala> addAhem _
res0: String => java.lang.String = <function1>
Well, this:
addUhum _
is an eta expansion. It converts methods into functions. On the other hand, this:
addUhum(_)
is an anonymous function. In fact, it is a partial function application, in that this parameter is not applied, and the whole thing converted into a function. It expands to:
x => addUhum(x)
The exact rules for expansion are a bit difficult to explain, but, basically, the function will "start" at the innermost expression delimiter. The exception is partial function applications, where the "x" is moved outside the function -- if _
is used in place of a parameter.
Anyway, this is how it expands:
val ummThenAhem = x => addAhem(x).compose(y => addUmm(y))
Alas, the type inferencer doesn't know the type of x or y. If you wish, you can see exactly what it tried using the parameter -Ytyper-debug
.
I believe the tutorial was written for an earlier version of Scala (probably 2.7.7 or earlier). There have been some changes in the compiler since then, namely, extensions to the type system, which now cause the type inferencing to fail on the:
addUhum(_).compose(addAhem(_))
The lifting to a function still works with that syntax if you just write:
addUhum(_)
addAhem
is a method. compose
method is defined on functions. addAhem _
converts addAhem
from method to function, so compose
can be called on it. compose
expects a function as it's argument. You are giving it a method addUmm
by converting addUmm
into a function with addUmm _
(The underscore can be left out because the compiler can automatically convert a method into a function when it knows that a function is expected anyway). So your code:
addAhem _ compose addUmm
is the same as
(addAhem _).compose(addUmm)
but not
addAhem(_).compose(addUmm(_))
PS I didn't look at the link you provided.