在Scala中调用curry函数?

时间:2016-06-18 21:57:47

标签: scala function functional-programming higher-order-functions currying

所以我对Scala中的curry函数的工作方式感到有些困惑。 我有以下代码编译,但我不确定如何!

def fixedPoint(f: Double => Double, initialGuess: Double) = {
   //dummy impl, does nothing.
}

def averageDamp(f: Double => Double)(x: Double) = (x + f(x))/2

def sqrt(x: Int) = {
  fixedPoint(averageDamp(y => x/y))(1)
}

这段代码编译得很好,但我认为averageDamp还需要另外一个参数?所以它应该是:

fixedPoint(averageDamp(y=> x/y)(1))(1)

但是这不能编译,我得到一条消息说类型不匹配;发现:双重要求:双⇒双重

以下不编译,这是有道理的:

val num = averageDamp(y => x/y)

这给出了编译错误消息:"缺少对象Foo中方法averageDamp的参数列表未应用的方法仅转换为  当预期函数类型时函数。"

所以我不确定为什么在调用一个参数调用averageDamp时会调用fixedPoint,但是当我自己调用它时无法编译。

任何帮助都会很棒。

1 个答案:

答案 0 :(得分:6)

这是编译

的代码
def fixedPoint(f: Double => Double, initialGuess: Double) = {
   //dummy impl, does nothing.
}

def averageDamp(f: Double => Double)(x: Double) = (x + f(x))/2

def sqrt(x: Int) = {
  fixedPoint(averageDamp(y => x/y), 1)
}

在这一行

fixedPoint(averageDamp(y => x/y), 1)

即使averageDamp需要一个更多的参数列表(还有一个参数),也可以不放置它。实际上,这就是为什么它首先被定义为curry的原因 - 所以你可以将它作为一个函数使用。

scala>     val num = averageDamp(y => 5/y)(1)
num: Double = 3.0

会给你一个类型Double的结果,正如你所料。

如果您没有通过第二个参数列表,您可以收到一个函数

val fun = averageDamp(y => 5/y)

给出错误尝试告诉您需要通知编译器您希望fun成为函数。您可以通过以下方式执行此操作:

scala>     val fun: Double => Double = averageDamp(y => 5/y)
fun: Double => Double = <function1>
scala>     val fun = averageDamp(y => 5/y) _
fun: Double => Double = <function1>

现在看看fixedPoint

def fixedPoint(f: Double => Double, initialGuess: Double)

它需要一个函数Double => Double,所以我们可以传递它

fixedPoint(averageDamp(y => 5/y), 1)

编译器知道第一个参数应该是一个函数,并且根据这个知识,它将此方法转换为尚未获取x: Double参数的函数,并将返回(x + f(x))/2