簡體   English   中英

Scala lazy val解釋

[英]Scala lazy val explanation

我正在使用Coursera中的Scala課程中的函數式編程,我很難理解這段代碼片段 -

def sqrtStream(x: Double): Stream[Double] = {
  def improve(guess: Double): Double = (guess+ x/ guess) / 2
  lazy val guesses: Stream[Double] = 1 #:: (guesses map improve)
  guesses
}

當我做sqrtSteam(4).take(10).toList時,這種方法會以遞增的准確度順序找到10個近似4的平方根。

有人可以在這里解釋猜測的評估策略嗎? 我懷疑當猜測的第二個價值被提升時,猜測的價值取代了什么?

讓我們從簡化的例子開始:

 scala> lazy val a: Int  = a + 5
 a: Int = <lazy>

 scala> a
 stack overflow here, because of infinite recursion

所以a重新計算直到它得到一些穩定的值,就像這里:

scala> def f(f:() => Any) = 0 //takes function with captured a - returns constant 0
f: (f: () => Any)Int

scala> lazy val a: Int  = f(() => a) + 5
a: Int = <lazy>

scala> a
res4: Int = 5 // 0 + 5

你可以用def f(f: => Any) = 0替換def f(f:() => Any) = 0 ,所以a定義看起來像是真的傳遞給了f: lazy val a: Int = f(a) + 5

流使用相同的機制 - guesses map improve將作為名稱傳遞的參數傳遞(並且鏈接到懶惰a lambda將保存在Stream中,但是直到請求尾部才計算),所以它就像lazy val guesses = #::(1, () => guesses map improve) 當你調用guessess.head - 不會評估tail; guesses.tail將懶惰地返回Stream (improve(1), ?) guesses.tail.tail Stream (improve(1), ?)guesses.tail.tail將是Stream(improve(improve(1)), ?) guesses.tail.tail Stream(improve(improve(1)), ?)等等。

您可以通過修改map函數輕松找出正在發生的事情,如scaladoc示例中所述

scala> def sqrtStream(x: Double): Stream[Double] = {
     |   def improve(guess: Double): Double = (guess + x / guess) / 2
     |   lazy val guesses: Stream[Double] = 1 #:: (guesses map {n =>
     |     println(n, improve(n))
     |     improve(n)
     |   })
     |   guesses
     | }
sqrtStream: (x: Double)Stream[Double]

輸出是:

scala> sqrtStream(4).take(10).toList
(1.0,2.5)
(2.5,2.05)
(2.05,2.000609756097561)
(2.000609756097561,2.0000000929222947)
(2.0000000929222947,2.000000000000002)
(2.000000000000002,2.0)
(2.0,2.0)
(2.0,2.0)
(2.0,2.0)
res0: List[Double] = List(1.0, 2.5, 2.05, 2.000609756097561, 2.0000000929222947, 2.000000000000002, 2.0, 2.0, 2.0, 2.0)

guesses的價值不是替代的。 流類似於列表,但僅在需要時才對其元素進行評估,然后將其存儲,因此下次訪問它們時,評估將不再必要。 對流本身的引用不會改變。

在示例Αλεχει上寫道,Scala API中有一個很好的解釋: http//www.scala-lang.org/api/current/index.html#scala.collection.immutable.Stream

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM