I’m learning more about Scala, and I’m having a little trouble understanding the example of anonymous functions in http://www.scala-lang.org/node/135. I’ve copied the entire code block below:
object CurryTest extends Application {
def filter(xs: List[Int], p: Int => Boolean): List[Int] =
if (xs.isEmpty) xs
else if (p(xs.head)) xs.head :: filter(xs.tail, p)
else filter(xs.tail, p)
def modN(n: Int)(x: Int) = ((x % n) == 0)
val nums = List(1, 2, 3, 4, 5, 6, 7, 8)
println(filter(nums, modN(2)))
println(filter(nums, modN(3)))
}
I’m confused with the application of the modN function
def modN(n: Int)(x: Int) = ((x % n) == 0)
In the example, it’s called with one argument
modN(2) and modN(3)
What does the syntax of modN(n: Int)(x: Int) mean?
Since it’s called with one argument, I’m assuming they’re not both arguments, but I can’t really figure out how the values from nums get used by the mod function.
This is a fun thing in functional programming called currying. Basically Moses Schönfinkel and latter Haskell Curry (Schonfinkeling would sound weird though…) came up with the idea that calling a function of multiple arguments, say
f(x,y)is the same as the chain of calls{g(x)}(y)org(x)(y)wheregis a function that produces another function as its output.As an example, take the function
f(x: Int, y: Int) = x + y. A call tof(2,3)would produce5, as expected. But what happens when we curry this function – redefine it asf(x:Int)(y: Int)and call it asf(2)(3). The first call,f(2)produces a function taking an integeryand adding2to it -> thereforef(2)has typeInt => Intand is equivalent to the functiong(y) = 2 + y. The second callf(2)(3)calls the newly produced functiongwith the argument3, therefore evaluating to5, as expected.Another way to view it is by stepping through the reduction (functional programmers call this beta-reduction – it’s like the functional way of stepping line by line) of the
f(2)(3)call (note, the following is not really valid Scala syntax).So, after all this talk,
f(x)(y)can be viewed as just the following lambda expression(x: Int) => {(y: Int) => x + y}– which is valid Scala.I hope this all makes sense – I tried to give a bit of a background of why the
modN(3)call makes sense 🙂