このコードを考えてみてください(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
ます。
2番目の例の問題は何ですか?混乱していると思いfilter
ますが、理由がわかりません。それはを返すStream
ので、それは評価を熱心にさせません(私は正しいですか?)