次のコードは "* 1"を出力します。どのような不可解だが、私がコメントを削除した場合、それは私がすべてのなぜ私のストリームでtakeWhileが動作しないのですか
var max = 0
lazy val list: Stream[Int] = 1 #:: Stream.from(2)
list.takeWhile {
x =>
max = x
x < 4
}//.foreach(println)
println("*" + max)
次のコードは "* 1"を出力します。どのような不可解だが、私がコメントを削除した場合、それは私がすべてのなぜ私のストリームでtakeWhileが動作しないのですか
var max = 0
lazy val list: Stream[Int] = 1 #:: Stream.from(2)
list.takeWhile {
x =>
max = x
x < 4
}//.foreach(println)
println("*" + max)
ファーストを期待していたものである「* 4」を返している:あなたの2行目のlazy
やっていないもの、あなたはそれを削除して取得することができます同じ結果。
:それはちょうど別のStream
を返し、それが必要になるまで、そのストリームの先頭過去何が評価されないことにtakeWhile
は、実際怠け者です。次のことを考えてみましょう:
val s = Stream.from(1).takeWhile(_ > 0)
をあなたと私はs
が無限ストリームをするつもりであることを知っているが、我々はREPLを起動し、これを入力した場合、それを評価するために、完全に幸せです:
scala> val s = Stream.from(1).takeWhile(_ > 0)
s: scala.collection.immutable.Stream[Int] = Stream(1, ?)
あなたの例でも同じことが起こっています。takeWhile
に渡された(Int) ⇒ Boolean
は、ストリームの先頭を超えて何も供給されず、foreach
のようなものが必要になるまで供給されません。
あなたはtakeWhile
述語の内部println
のようなものを追加することで、より劇的にこれを見ることができます:
scala> val s = Stream.from(1).takeWhile { x => println("Checking: " + x); x < 4 }
Checking: 1
s: scala.collection.immutable.Stream[Int] = Stream(1, ?)
scala> val l = s.toList
Checking: 2
Checking: 3
Checking: 4
l: List[Int] = List(1, 2, 3)
明らかに我々はの評価を強制するまで、述語のみ、ストリームのヘッドのために呼び出されますストリームの残りの部分をtoList
と呼んでください。