所以我对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,但是当我自己调用它时无法编译。
任何帮助都会很棒。
答案 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