This question already has answers here:
Understanding Currying in Scala

(3个答案)


2年前关闭。





def sum(f: Int => Int): (Int, Int) => Int = {
    def sumF(a: Int, b: Int): Int =
        if (a > b) 0
        else f(a) + sumF(a + 1, b)
    sumF
}

def sumCubes    = sum(a => a * a * a)


sumCubes // output Function2
sumCubes(1,10) // output 3025.
sumCubes() // doesn't work


我觉得我不太理解咖喱。在第一条语句中,我们不带参数地调用sumCubes,因此sum以匿名函数作为参数被调用并返回一个function2。

在第二次和第三次调用中真正发生了什么,
我们为什么能做

sum(a => a * a * a)(1,10)


但不是

sumCubes()(1,10)


我的理解是,在sum(a => a * a * a)(1,10)中,我们部分地将sum应用于匿名函数,该函数返回一个Function2,该函数将应用于第二对参数(1,10),因此得到3025,

但是,在sumCubes()(1,10)的情况下也会发生同样的情况,首先调用不带参数的sumCubes,反过来会使用匿名函数调用sum,并且返回的Function2将应用于(1,10)

为什么sumCubes(1,10)起作用但sumCubes()(1,10)不起作用,sumCubessumCubes()不应是同一件事,即函数sumCubes的调用。另外,如果一个简单的引用sumCubes正在调用它,我该如何传递它。我觉得我不太了解Scala的基本知识。

最佳答案

Scala的方法可以有多个参数列表。

例如,下面的方法foo具有十个参数列表,其中前七个为空:

def foo()()()()()()()(a: Int)(b: Int)(c: Int): Int = a + b + c


您可以按以下方式调用它:

println(foo()()()()()()()(1)(20)(300))


并显示321

请注意,在调用方法时,参数列表的数量以及每个列表中的参数数量(以及它们的类型)必须与声明匹配。

另一个例子。以下方法具有两个参数列表:

def bar(i: Int)(f: Int => Int) = f(i)


您可以按以下方式调用它:

bar(42)(x => x * x)


但不是

bar()(x => x * x)
bar()(42)(x => x * x)
bar(42)()


或类似的东西。

完全类似,如果您定义的方法的参数列表为零

def baz = (x: Int) => x * x


那么您也必须使用零参数列表来调用它:

baz


由于它返回Int => Int函数,因此您当然可以将结果应用于Int

baz(42)


(baz)(42)相同,但是您不能执行以下操作:

baz()(42)


因为baz本身没有参数列表,并且()不包含单个整数参数。



请注意,以上所有内容实际上都是一种简化:在某些情况下,可以在不带括号的情况下调用具有空参数列表的方法,即def foo(): Unit = ...可以作为foo调用而没有()。这有点strange feature,我不能确切地说出它为什么存在。我最好的猜测是:它与java-interop有关,您真的想在零进制getter上省略括号。

10-07 14:53