这两种语义不同的原因是方法和功能不是一回事。
方法是全功能的JVM方法,而函数是值(即类的实例,如Function1
,Function2
等)。
所以
def sum(x: Int)(y: Int)(z: Int) = x + y + z
和
val sum = (x: Int) => (y: Int) => (z: Int) => x + y + z
看似相同,但首先是一种方法,而第二个是Function1[Int, Function1[Int, Function1[Int, Int]]]
当您尝试使用一种方法,其中一个函数值是预期的,编译器会自动将其转换为函数(称为eta-expansion的进程)。
但是,在某些情况下,编译器不会自动扩展这些方法,例如您明确想要部分应用它的案例。
使用_
触发eta扩展,所以一个方法转换为函数,并且每个人都很高兴。
按照Scala的规范,你也可以注释预期的类型,在这种情况下自动进行扩展:
def sum(x: Int)(y: Int)(z: Int) = x + y + z
val sumFunction: Int => Int => Int => Int = sum
这是一样的道理,为什么
def sum(x: Int, y: Int) = x + y
List(1,2,3).reduce(sum)
作品,即我们传递了一个明确需要函数的方法。
这里的时候斯卡拉执行ETA膨胀的更深入的讨论:https://stackoverflow.com/a/2394063/846273
关于其选择采用,我会指出你this answer,这是非常详尽的。
http://stackoverflow.com/questions/4915027/two-ways-of-currying-in-scala-whats-the-use-case-for-each/4916606#4916606 – Debilski 2014-10-02 12:51:43