Moebius
Moebius

Reputation: 6508

Understanding Currying Implemention in Scala

As an exercise for functional programing in Scala, we have to create a function which currifies. I couldn't create this one so I looked the solution:

def curry[A,B,C](f: (A, B) => C): A => (B => C) =
  a => b => f(a, b)

I looked at it, have been able to play a little with it, but I don't completely understand it.

Could you explain it to me in details ? Where do the little variables a and b come from ? What is the meaning of => in a => b ?

Upvotes: 1

Views: 216

Answers (1)

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149538

curry is a Higher Order Function (method, in Scala terms) which takes a single argument, f. f itself is a function, which takes two arguments of type A and B and returns a result of type C. The methods (curry) return type is also a function of type Function1[A, Function1[B, C]].

Where do the little variables a and b come from

The parameters a and b are two values which are passed to f. a is of type A and b is of type B and are part of anonymous function syntax. Think of them as placeholders for future values which will be used when the method is invoked.

Let's use curry in an example:

scala> def curry[A,B,C](f: (A, B) => C): A => (B => C) =
     |   a => b => f(a, b)
curry: [A, B, C](f: (A, B) => C)A => (B => C)

We'll pass a function taking two Int's and returning an Int and see what happens:

scala> curry((x: Int, y: Int) => x + y)
res0: Int => (Int => Int) = <function1>

We passed a function which takes two parameters, x and y of type Int, and returns the sum of the two values. In return we received a function of type Function1[Int, Function1[Int, Int]] which is a function taking a single Int value and which returns a Function1 itself, taking a Int value and returning an Int.

Now let's what happens when we pass an Int value to res0:

scala> res0(1)
res1: Int => Int = <function1>

As expected, invoking res0 returns a Function1[Int, Int]. If we pass another Int to res1, we'll receive the sum:

scala> res1(1)
res3: Int = 2

We can also invoke res0 and pass two parameter lists to get the result:

scala> res0(1)(1)
res2: Int = 2

In my example, I used Int as the type for all parameters for simplicity. But since curry is defined for three types A, B and C we can create more complicated functions where the types are different from each other.

Upvotes: 7

Related Questions