以下代码有效,但我不太清楚参数如何映射到参数列表。请注意我是Scala的新手。
import Math.abs
val tolerance = 0.0001
def isCloseEnough(x: Double, y: Double) =
abs((x - y) / x) / x < tolerance
def fixedPoint(f: Double => Double)(firstGuess: Double) = {
def iterate(guess: Double): Double = {
val next = f(guess)
if (isCloseEnough(guess, next)) next
else iterate(next)
}
iterate(firstGuess)
}
def averageDamp(f: Double => Double)(x: Double) = (x + f(x)) / 2
def sqrt(x: Double) =
fixedPoint(averageDamp(y => x / y))(1.0)
sqrt(2.0)
上面sqrt
函数的正文为fixedPoint(averageDamp(y => x / y))(1.0)
,其中
(y => x / y)
映射到(f: Double => Double)
函数的averageDamp
和
(1.0)
映射到(firstGuess: Double)
函数的fixedPoint
,但
似乎没有映射到(x: Double)
函数的averageDamp
。
提前谢谢。
答案 0 :(得分:2)
这称为currying。真正发生的是averageDamp(y => x / y)
被解释为函数:Double => Double
,因为一旦将第一个参数列表设置为一组特定值,就会得到一个带有第二个参数列表的函数。 / p>
例如,请考虑以下代码:
def multiply(x: Double)(y: Double) = x * y
val multiplyByFive: Double => Double = multiply(5)
println(multiplyByFive(2)) // 10
println(multiplyByFive(6)) // 30
如您所见,将multiply
仅应用于两个参数列表的事实创建了第二个参数列表(此处为(y: Double)
)的新函数,该列表具有一组固定的值第一个参数列表(这里是(5)
)。
另一种写这个的等效方式,可能会更加明确,如下:
val multiplyByFive: Double => Double = multiply(5)(_)
这里我们使用两个参数列表显式应用该函数,但是使用第二个通配符,这是一种告诉编译器创建一个函数的方法,该函数用函数的参数替换下划线。