Somewhat similar to Stack Overflow question Compose and andThen methods, I've been working through Twitter's Scala School tutorial and quickly ran into the same problem that a commenter had (which was great, because I went to bed thinking my problem was solved).
In the tutorial, it defines two methods as such:
def addUmm(x: String) = x + " umm"
def addAhem(x: String) = x + " ahem"
and while in newer versions of Scala, you can't call compose on them as such: addUmm(_).compose(addAhem(_))
, the accepted answer (and some of the other answers seem to hinge upon the fact that addUmm
and addAhem
are methods, not functions, which creates an issue when trying to call compose. I went to bed satisfied, having successfully run:
scala> ((s: String) => s + " umm").compose((s: String) => s + " ahem")
res0: String => java.lang.String = <function1>
Cool. The issue is that while not being able to compose methods makes some sense, when I the same thing with values I know evaluate to Function1
:
val a = (s: String) => s + " umm"
val b = (s: String) => s + " ahem"
val c = a(_).compose(b(_))
Well, that last line coughs up the same error that the original question did, even though they're partial applications of functions this time, not methods. One of the answers in the original question (highly-ranked, but not the accepted answer) seems to hint that it has to do with how the partial application is expanded, what is the explanation?
For a Scala newbie, the fact that the inferencer gets a(_).compose(b(_))
wrong no matter if you explicitly specify _: String
both places, but a.compose(b)
does is somewhat confusing.
The Partially applied functions are the functions which are not applied on all the arguments defined by the stated function i.e, while invoking a function, we can supply some of the arguments and the left arguments are supplied when required.
Function composition is a way in which a function is mixed with other functions. During the composition the one function holds the reference to another function in order to fulfill it's mission.
Scala functions are first class values. Difference between Scala Functions & Methods: Function is a object which can be stored in a variable. But a method always belongs to a class which has a name, signature bytecode etc. Basically, you can say a method is a function which is a member of some object.
Here, Scala function is first-class value. Scala also has methods, but these differ only slightly from Scala function. A method belongs to a class; it has a name, a signature, [optionally, ] some annotations, and some bytecode. A function is a complete object that we can store in a variable.
a(_).compose(b(_))
expands to x => { a(x).compose(y => b(y) }
. Hence the error. What you want is (x => a(x)).compose(y => b(y))
. Adding a pair of parentheses fixes this.
scala> (a(_)).compose(b(_: String))
res56: String => java.lang.String = <function1>
scala> res56("hello")
res57: java.lang.String = helloahemumm
But since a
and b
are functions, you can avoid all this cruft and simply do a compose b
.
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