斯卡拉高阶函数有点困惑 [英] Scala Higher Order Function Little Confused

查看:122
本文介绍了斯卡拉高阶函数有点困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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

  • Scala工作表显示在我的calculateAverate函数中b


    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 

    是一个函数定义,它有两个参数:


    1. 一个函数f,它带有双,它返回 Double

    2. 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 

    可能看起来比较熟悉。



    calculateAverate 是一个Double,因为你将传递的函数f应用于x的结果加上x给出了一个 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:

    1. a function "f" which takes a parameter of type Double which returns a Double and
    2. 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屋!

    查看全文
  • 登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆