Why are there two sets of arguments/parenthesis in this Scala method definition?

Solution 1:

This is named Currying. A curried function is when it has the type A => B => C.

The function def foo(a: A, b: B): C has the type (A, B) => C. On the other hand, the function def curriedFoo(a: A)(b: B): C has the type A => B => C. With the curried function you could do def curriedFooWithA = curriedFoo(a) which has the type B => C. You don't have to provide all the argument in one go.

So, in your case you can provide the amount, a, and b. You'll get a function taking a Transaction. Another case would be a function of the type Request => DataBase => Int, where you just provide the Request, and finally when you really need to run the request, provide the DataBase to which the request has to be sent.

The type (A, B) => C and A => B => C are isomorphic. Scala provides the tupled and uncurried that do just that.

def curriedFoo(a: A)(b: B): C = a => b => foo(a, b)

def foo(a: A, b: B): C => (a, b) => curriedFoo(a, b)