斯卡拉高阶函数有点困惑 [英] Scala Higher Order Function Little Confused
问题描述
我在Worksheet中运行下面的Scala代码:
package src.com.sudipta.week2.coursera
import scala.math.abs
import scala.annotation.tailrec
object FixedPoint {
println(Welcome to the Scala worksheet)//>欢迎来到Scala工作表
val tolerance = 0.0001 //>容差:Double = 1.0E-4
def isCloseEnough(x:Double,y:Double):Boolean = {
abs((x-y)/ x)/ x <宽容
} //> isCloseEnough:(x:Double,y:Double)布尔值
def fixedPoint(f:Double =&Double; Double)(firstGuess:Double):Double = {
@tailrec
def iterate(guess :Double):Double = {
val next = f(guess)
if(isCloseEnough(guess,next))next
else iterate(next)
}
iterate(firstGuess)
} //> fixedPoint:(f:Double => Double)(firstGuess:Double)Double
def myFixedPoint = fixedPoint(x => 1 + x / 2)(1)//> myFixedPoint:=> Double
myFixedPoint //> res0:Double = 1.999755859375
def squareRoot(x:Double)= fixedPoint(y =>(y + x / y)/ 2)(1)
//> squareRoot:(x:Double)Double
squareRoot(2)//> res1:Double = 1.4142135623746899
def calculateAverate(f:Double => Double)(x:Double)=(x + f(x))/ 2
//> calculateAverate:(f:Double =&Double)(x:Double)Double
def myNewSquareRoot(x:Double):Double = fixedPoint(calculateAverate(y => x / y))(1)
//> myNewSquareRoot:(x:Double)Double
myNewSquareRoot(2)//> res2:Double = 1.4142135623746899
}
让我困惑的是:
- Scala工作表显示了我的fixedPoint函数
fixedPoint:(f:Double => Double)(firstGuess:Double)Double
这是什么?这个函数类型/函数定义还是我错过了这个术语?
基本上我可以用英语解释这个函数吗?
$ b $ ul
lockquote
calculateAverate:(f:Double => Double)(x:Double)Double
但是在我看来,函数的返回类型是Double,但我期待Double => Double。原因是我打算使用这个与fixedPoint,它预计Double => Double如下所示:
lockquote
def myNewSquareRoot(x:Double): Double = fixedPoint(calculateAverate(y
=> x / y))(1)
请帮我理解更高订单功能/更加清晰的卷曲。
函数
def fixedPoint(f:Double =&Double; Double)(firstGuess:Double):Double
是一个函数定义,它有两个参数:
- 一个函数f,它带有
双,它返回
Double
和 - a
Double 名为firstGuess的值
,并返回 Double
。将单个参数分成它们自己的括号组允许函数在currying中使用:
def mySqrtCalc(x:Double )(firstGuess:Double):Double = {...}
val mySqrtFunc = mySqrtCalc(2.0)_
$ b $ v val v = mySqrtFunc(1)// parameter firstGuess is设置为1
除了柯里化的功能,这相当于不安全的版本
def fixedPoint(f:Double => Double,firstGuess:Double):Double
可能看起来比较熟悉。
Double
,因为f是一个函数 Double => Double
。
您可以在<$ c中以curry方式使用 calculateAverate
$ c> myNewSquareRoot 方法体,它只给出两个参数中的第一个参数,省略第二个参数,该参数取自外部 fixedPoint
方法。省略 calculateAverate
的第二个参数为您提供了一个方法 Double => Double
,这是 fixedPoint
方法。
您可以插入一些 println(s< methodname> value = $ value)
来观察执行流程和理解方法调用订单。
I was running the below Scala code in Worksheet:
package src.com.sudipta.week2.coursera
import scala.math.abs
import scala.annotation.tailrec
object FixedPoint {
println("Welcome to the Scala worksheet") //> Welcome to the Scala worksheet
val tolerance = 0.0001 //> tolerance : Double = 1.0E-4
def isCloseEnough(x: Double, y: Double): Boolean = {
abs((x - y) / x) / x < tolerance
} //> isCloseEnough: (x: Double, y: Double)Boolean
def fixedPoint(f: Double => Double)(firstGuess: Double): Double = {
@tailrec
def iterate(guess: Double): Double = {
val next = f(guess)
if (isCloseEnough(guess, next)) next
else iterate(next)
}
iterate(firstGuess)
} //> fixedPoint: (f: Double => Double)(firstGuess: Double)Double
def myFixedPoint = fixedPoint(x => 1 + x / 2)(1)//> myFixedPoint: => Double
myFixedPoint //> res0: Double = 1.999755859375
def squareRoot(x: Double) = fixedPoint(y => (y + x / y) / 2)(1)
//> squareRoot: (x: Double)Double
squareRoot(2) //> res1: Double = 1.4142135623746899
def calculateAverate(f: Double => Double)(x: Double) = (x + f(x)) / 2
//> calculateAverate: (f: Double => Double)(x: Double)Double
def myNewSquareRoot(x: Double): Double = fixedPoint(calculateAverate(y => x / y))(1)
//> myNewSquareRoot: (x: Double)Double
myNewSquareRoot(2) //> res2: Double = 1.4142135623746899
}
What is making me confused are:
- Scala worksheet is showing below for my fixedPoint function
fixedPoint: (f: Double => Double)(firstGuess: Double)Double
What is this? Is this function type/ function definition or I am missing the term? Basically how I can explain this function in English?
- Scala worksheet is showing below for my calculateAverate function
calculateAverate: (f: Double => Double)(x: Double)Double
But it looks to me the return type of my function is Double, but I was expecting Double => Double. The reason is I am going to use this with fixedPoint which expects Double => Double like below:
def myNewSquareRoot(x: Double): Double = fixedPoint(calculateAverate(y => x / y))(1)
Please help me to understand Higher Order Function / Currying more clearly. Thanks in advance.
The function
def fixedPoint (f: Double => Double)(firstGuess: Double):Double
is a function definition which takes two arguments:
- a function "f" which takes a parameter of type
Double
which returns aDouble
and - a
Double
value named "firstGuess"
and returns a Double
. The separation of the single parameters into their own parenthesis groups allows the function to be used in currying:
def mySqrtCalc(x:Double)(firstGuess:Double):Double = {...}
val mySqrtFunc = mySqrtCalc(2.0) _
val v = mySqrtFunc(1) // parameter firstGuess is set to 1
Beside the ability for currying, this is equivalent to the uncurried version
def fixedPoint (f: Double => Double,firstGuess: Double):Double
which might look more familiar to you.
The result of the calculateAverate
is a Double because you add up the result of applying the passed function f to x with x which gives you a Double
because f is a function Double => Double
.
You use calculateAverate
method in a curried way in your myNewSquareRoot
method body, by giving only the first of both parameters in first place and omitting the second one, which is taken from the from the outer fixedPoint
method. Omitting the second parameter of calculateAverate
gives you a method Double=>Double
as it is required by the fixedPoint
method.
You might insert some println(s"<methodname> value=$value")
to observe the execution flow and understand the method call order.
这篇关于斯卡拉高阶函数有点困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!