Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function composition of methods, functions, and partially applied functions in Scala

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.

like image 646
Marc Bollinger Avatar asked Oct 07 '11 05:10

Marc Bollinger


People also ask

What are partially applied functions in Scala?

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.

What is function composition in Scala?

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.

What is difference between function and method in Scala?

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.

What is function type in Scala?

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.


1 Answers

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.

like image 66
missingfaktor Avatar answered Sep 30 '22 17:09

missingfaktor