3

我只是 Scala 的新手,为什么 Scala 提供“咖喱函数”让我有点困惑,例如:

//curried function
def add(lhs: Int)(rhs: Int) = lhs + rhs
//so we can do partially binding like
val add1 = add(1)_

它令人困惑,因为 Scala 已经为普通函数提供了“部分应用程序”,例如,

//normal function
def add(lhs: Int, rhs: Int) = lhs + rhs
//also supports partially application
val add1 = add(1, _: Int) 

所以我的问题是:除了部分应用程序之外,在 Scala 中使用 curried 函数而不是普通函数还有其他意义吗?

EDT1:感谢您的回复。我想我从以下所有答案中学到了新东西。

4

3 回答 3

8

抛开理论动机(参见:与Wikipedia 中的函数应用对比),有一个实际含义。当最后一个参数是代码块时,语法更简单,更易读。

比较以下方法:

def test1(name: String, callback: => Unit) {}
def test2(name: String)(callback: => Unit) {}

第二个方法调用看起来好多了,比较:

test("abc", {
    //some code
})

test2("abc") {
    //some code
}
于 2012-09-28T07:52:13.520 回答
5
  • 更好的语法: add(1) 而不是 add(1,_)
  • 类型推断从左到右的参数列表。例如,这用于集合的折叠方法。
  • 隐式参数列表也需要它们。

当然,您可以争辩说最后两个可能以不同的方式实现。

于 2012-09-28T07:51:39.710 回答
2

我不熟悉 currying 背后的理论(到目前为止),但我知道至少一种具体情况,currying 效果更好:调用带有一对花括号而不是括号的函数仅适用于单参数函数。因此,您可以为具有两个参数列表且每个参数列表的柯里化函数执行此操作,但不适用于已部分应用于一个参数的普通函数。

这在实现控制结构或 DSL 时特别有用,其中函数的某些参数本身就是匿名函数。这方面的一个例子来自Programming in Scala,第 9.4 节:

val file = new File("date.txt")

withPrintWriter(file) {
  writer => writer.println(new java.util.Date)
}
于 2012-09-28T07:53:13.953 回答