2017-02-26 229 views
1

以下代码有效,但我不太了解参数如何映射到参数列表。请注意我是Scala新手。在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)映射到averageDamp功能的(f: Double => Double)

(1.0)映射到fixedPoint功能的(firstGuess: Double)

看起来没有映射到averageDamp函数的(x: Double)

预先感谢您。

回答

2

这叫做currying。实际发生的事情是,averageDamp(y => x/y)被解释为一个函数:Double => Double,因为一旦您将第一个参数列表设置为一组特定的值,您将获得一个采用第二个参数列表的函数。

例如,请考虑下面的代码:

def multiply(x: Double)(y: Double) = x * y 

val multiplyByFive: Double => Double = multiply(5) 
println(multiplyByFive(2)) // 10 
println(multiplyByFive(6)) // 30 

正如你看到的,只有一个参数列表出来的2个粘贴multiply的事实造成的第二个参数列表(这里(y: Double))的新功能对于第一个参数列表(此处为(5))具有固定的一组值。

写这个,这或许将是您更明确的另一种等价的方式,如下:

val multiplyByFive: Double => Double = multiply(5)(_) 

在这里,我们明确地用两个参数列表应用功能,但使用通配符第二,这是一种告诉编译器创建函数的函数,该函数用函数的参数替换下划线。

+0

谢谢,现在我明白了。 – Eddie