2

私は深く「ネストされた」理解力を持っており、x、y、zの3つのレベルに簡略化されています。xaだけをStream作成すると、yとzの計算も怠惰になることを望んでいました。

val stream = for {
  x <- List(1, 2, 3).toStream
  y <- List("foo", "bar", "baz")
  z = {
    println("Processed " + x + y)
    x + y
  }
} yield z

stream take (2) foreach (doSomething)

しかし、これは3つのプリントから明らかなように、3つの要素すべてを計算します。最初の2つだけを計算したいのは、これらがすべてストリームから取得するためです。toStream2番目などを呼び出すことでこれを回避できListます。理解のあらゆるレベルでそれを呼ぶよりも良い方法はありますか?

4

1 に答える 1

4

印刷されるものは次のとおりです。

Processed 1foo
Processed 1bar
Processed 1baz
stream: scala.collection.immutable.Stream[String] = Stream(1foo, ?)

scala> stream take (2) foreach (println)
1foo
1bar

aのヘッドStreamは常に厳密に評価されるため、 etcが表示され、 Processed 1fooetcは表示されませんProcessed 2foo。これは、ストリームを作成するとき、より正確には、のヘッドstreamが評価されるときに印刷されます。

結果として得られる各要素を1つずつ処理するだけの場合は、すべてのジェネレーターをStreamsにする必要があります。toStream以下の例のように、最初にストリームにすることで、呼び出しを回避できます。

streamはでStream[String]あり、その頭を評価する必要があります。値を熱心に計算したくない場合は、ダミー値を追加するか、より適切に値を作成することができますstream lazy

lazy val stream = for {
  x <- Stream(1, 2, 3)
  y <- Stream("foo", "bar", "baz")
  z = { println("Processed " + x + y); x + y }
} yield z 

これは、各値を取得するまで「処理」を行いません。

scala> stream take 2 foreach println
Processed 1foo
1foo
Processed 1bar
1bar
于 2012-03-24T02:57:37.910 に答える