【问题标题】:Scala Stream call-by-need (lazy) vs call-by-nameScala Stream call-by-need (lazy) vs call-by-name
【发布时间】:2013-04-30 16:43:55
【问题描述】:

所以我知道按需调用只是按名称调用的记忆版本。在 Martin Odersky 在 Coursera 上的 FP 课程的第 7.3 课(惰性评估)中,他提到如果 Streams 是使用按名称调用来实现的,那么它可能会导致计算复杂度的爆炸。

这种爆炸的例子是什么?

点名:

def cons[T](hd: T, tl: => Stream[T]) = new Stream[T] {
  def head = hd
  def tail = tl
  ...
}

按需调用:

def cons[T](hd: T, tl: => Stream[T]) = new Stream[T] {
  def head = hd
  lazy val tail = tl
  ...
}

【问题讨论】:

    标签: scala stream


    【解决方案1】:

    例如斐波那契数列,通过添加前两个元素形成后继来实现。如果没有 memoization,那么序列长度会线性减慢(和堆栈增长):

    scala> lazy val fib: Stream[Int] = Stream.cons(0,
         | Stream.cons(1, fib.zip(fib.tail).map(p => p._1 + p._2)))
    fib: Stream[Int] = Stream(0, ?)
    

    this blog复制的懒惰(-sic-)示例

    【讨论】:

    • 请检查链接,
    【解决方案2】:

    deflazy val 都是懒惰的。不同之处在于def 每次被调用时都会重新评估。 lazy val 仅在第一次调用时才被评估,对它的任何调用都只会查看第一个评估值。

    使用def 意味着每次调用tail 时都会重新评估它。

    def randDef: () => Int = {
      val r = scala.util.Random.nextInt
      () => r
    }
    
    val randVal: () => Int = {
      val r = scala.util.Random.nextInt
      () => r
    }
    
    lazy val randLazyVal: () => Int = {
      val r = scala.util.Random.nextInt
      () => r
    }
    // defined function randDef
    // randVal: () => Int = ammonite.$sess.cmd18$Helper$$Lambda$2545/0x00000008013a4430@7466fa3
    // randLazyVal: () => Int = [lazy]
    
    randDef()
    // res8: Int = -693604502
    randDef()
    // res9: Int = 2056941756
    randDef eq randDef
    // res15: Boolean = false
    
    randVal()
    // res11: Int = 3
    randVal()
    // res12: Int = 3
    randVal eq randVal
    // res16: Boolean = true
    
    randLazyVal()
    // res13: Int = 99
    randLazyVal()
    // res14: Int = 99
    randLazyVal eq randLazyVal
    // res17: Boolean = true
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-23
      • 1970-01-01
      相关资源
      最近更新 更多