所以我理解,按需调用只是一个按名称调用的memoized版本.在Martin Odersky的课程FP课程中,在7.3课程(懒惰评估)中,他提到如果Streams是使用call-by-name实现的,那么它可能会导致计算复杂性的爆炸.
这种爆炸的例子是什么?
呼叫按姓名:
def cons[T](hd: T, tl: => Stream[T]) = new Stream[T] {
def head = hd
def tail = tl
...
}
Run Code Online (Sandbox Code Playgroud)
呼叫按需要:
def cons[T](hd: T, tl: => Stream[T]) = new Stream[T] {
def head = hd
lazy val tail = tl
...
}
Run Code Online (Sandbox Code Playgroud)
例如斐波那契数列,通过将前两个元素相加形成后继来实现。如果没有记忆,序列的长度将会线性减慢(和堆栈增长):
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, ?)
Run Code Online (Sandbox Code Playgroud)
从这个博客复制的懒惰示例(-sic-)
| 归档时间: |
|
| 查看次数: |
926 次 |
| 最近记录: |