考虑这段代码(取自Martin Odersky的“Scala 函数式编程原理”课程):
def sieve(s: Stream[Int]): Stream[Int] = {
s.head #:: sieve(s.tail.filter(_ % s.head != 0))
}
val primes = sieve(Stream.from(2))
primes.take(1000).toList
它工作得很好。请注意,这sieve
实际上不是尾递归(或者是吗?),即使Stream
' 的尾是惰性的。
但是这段代码:
def sieve(n: Int): Stream[Int] = {
n #:: sieve(n + 1).filter(_ % n != 0)
}
val primes = sieve(2)
primes.take(1000).toList
抛出StackOverflowError
。
第二个例子有什么问题?我filter
想把事情搞砸了,但我不明白为什么。它返回 a Stream
,所以它不会使评估变得急切(我是对的吗?)