Hari Rao
Hari Rao

Reputation: 3260

Difference between f(a,b) and f(a)(b) in Scala

I am very very new to Scala. I am reading a book called functional programming in scala by Paul Chiusano and Rúnar Bjarnason. So far I am finding it interesting. I see a solution for curry and uncurry

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

def uncurry[A,B,C](f: A => B => C): (A, B) => C = {
    (a,b) => f(a)(b)
  }

In Curry I understand f(a,b) which results in value of type C but in uncurry I do not understand f(a)(b). Can anyone please tell me how to read f(a)(b) or how is this resulting to a type of C or please refer me some online material that can explain this to me?

Thanks for your help.

Upvotes: 3

Views: 1092

Answers (3)

Hari Rao
Hari Rao

Reputation: 3260

In case if somebody is looking for an explanation. This link explains it better

def add(x:Int, y:Int) = x + y

add(1, 2)   // 3
add(7, 3)   // 10   

After currying

def add(x:Int) = (y:Int) => x + y

add(1)(2)   // 3
add(7)(3)   // 10

In the first sample, the add method takes two parameters and returns the result of adding the two. The second sample redefines the add method so that it takes only a single Int as a parameter and returns a functional (closure) as a result. Our driver code then calls this functional, passing the second “parameter”. This functional computes the value and returns the final result.

Upvotes: 2

stefanobaghino
stefanobaghino

Reputation: 12804

In the uncurry method you take a so-called "curried" function, meaning that instead of having a function that evaluates n arguments, you have n functions evaluating one argument, each returning a new function until you evaluate the final one.

Currying without a specific support from the language mean you have to do something like this:

// curriedSum is a function that takes an integer,
// which returns a function that takes an integer
// and returns the sum of the two
def curriedSum(a: Int): Int => Int = 
   b => a + b

Scala however provides further support for currying, allowing you to write this:

def curriedSum(a: Int)(b: Int): Int = a + b

In both cases, you can partially apply curriedSum, getting a function that takes an integer and sums it to the number you passed in originally, like this:

val sumTwo: Int => Int = curriedSum(2)
val four = sumTwo(2) // four equals 4

Let's go back to your case: as we mentioned, uncurry takes a curried function and turns it into a regular function, meaning that

f(a)(b)

can read as: "apply parameter a to the function f, then take the resulting function and apply the parameter b to it".

Upvotes: 3

J. Fraudeau
J. Fraudeau

Reputation: 126

Basically the return type of f(a) is a function of type B => C lets call this result g. If you then call g(b) you obtain a value of type C. f(a)(b) can be expanded to f.apply(a).apply(b)

Upvotes: 5

Related Questions