Scala中的curried函数背后的基本原理是什么?

时间:2012-09-28 07:40:38

标签: scala currying

我只是Scala的新手,对我来说似乎有点困惑,为什么Scala提供" curried函数"如:

//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:感谢您的回复。我想我已经从下面的所有答案中学到了新的东西。

3 个答案:

答案 0 :(得分:8)

将理论动机放在一边(参见:Contrast with partial function application在维基百科中 currying ),有一个实际意义。当最后一个参数是一个代码块时,语法更简单,更易读。

比较以下方法:

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

第二种方法调用看起来更好,比较:

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

test2("abc") {
    //some code
}

答案 1 :(得分:5)

  • 更好的语法:添加(1)而不是添加(1,_)
  • 从左到右参数列表中键入推断。例如,这在集合的折叠方法中使用。
  • 隐式参数列表也需要它们。

当然,你可以说最后两个可能会以不同的方式实施。

答案 2 :(得分:2)

我不熟悉currying背后的理论(至今),但我知道至少有一个具体情况,即currying工作得更好:调用带有一对花括号而不是括号的函数只能用于单参数功能。因此,您可以为具有两个参数列表的curried函数执行此操作,每个参数列表具有单个参数,但不适用于已部分应用于一个参数的普通函数。

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

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

withPrintWriter(file) {
  writer => writer.println(new java.util.Date)
}