Why does currying in Scala need multiple parameter lists?

后端 未结 2 1181
一生所求
一生所求 2021-01-04 19:11

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 */ }
相关标签:
2条回答
  • 2021-01-04 19:50

    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>
    
    0 讨论(0)
  • 2021-01-04 19:54

    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.

    0 讨论(0)
提交回复
热议问题