Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does currying in Scala need multiple parameter lists?

Tags:

scala

Suppose I have a function of 2 parameters that I need to apply partially, I need to define it as:

def f(a: Int)(b: Int) = { /* some code */ }

And then I can apply it partially as def fWithA = f(a) _

My question is: In order to curry a function why does Scala require that the parameters are declared using multiple parameter lists? It would be preferable to be able to curry any function as desired.

like image 245
pramodbiligiri Avatar asked Sep 30 '12 11:09

pramodbiligiri


2 Answers

Actually you can partially apply any method you want. Simply call the method and leave out params:

scala> def foo(a: Int, b: Int) = a*b
foo: (a: Int, b: Int)Int

scala> val x = foo(1,_: Int)
x: Int => Int = <function1>

scala> def bar(x: Int, y: Int, z: Int) = x*y+z
bar: (x: Int, y: Int, z: Int)Int

scala> bar(2,_:Int,6)
res0: Int => Int = <function1>

The only difference is, that you have to tell the compiler the type of the missing argument, because otherwise it could not decide between overloaded methods.

Another way, if you have a real function and not a method would be to call curried on the function:

scala> val f = {(x:Int, y:Int) => x*y}
f: (Int, Int) => Int = <function2>

scala> f.curried
res2: Int => (Int => Int) = <function1>

And you can also create a function from a method with the _:

scala> bar _
res6: (Int, Int, Int) => Int = <function3>

and then call curried on that:

scala> (bar _).curried
res5: Int => (Int => (Int => Int)) = <function1>
like image 163
drexin Avatar answered Sep 24 '22 20:09

drexin


A few reasons 'real' currying requires multiple parameter lists in Scala:

  • overloading. Unlike purely functional languages, in Scala you can overload methods. If you partially apply a function, the compiler may not be able to distinguish which overload you mean. The specification limits overloading resolution to the first parameter list.

  • error messages. "not enough arguments for method call" is a very useful (and easy to understand) error message. If one allowed currying for any method, the error message would be "required: but "some function type with many arrows" type.

  • performance. Running on the JVM makes it very efficient to call methods, while functions (going through an interface call) are slower.

like image 25
Iulian Dragos Avatar answered Sep 23 '22 20:09

Iulian Dragos