2012-03-24 9 views
0

私は深く「ネストされた」理解のために、x、y、zの3つのレベルに単純化されています。私はStream xを作ることを望ん怠惰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つだけを計算したいのですが、それらはストリームからすべて取るためです。私はListのようにtoStreamを呼び出すことでこれを回避することができます。理解のあらゆるレベルでそれを呼び出すよりも良い方法がありますか?

答えて

3

何それが印刷さがある:

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

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

Streamのヘッドは常に厳密にあなたがこれを使用すると、ストリームを作成するときに印刷された、あるいはより正確にされProcessed 1fooなどではなくProcessed 2fooなどを参照してください理由である、評価され、 streamの頭が評価されたとき。

結果の各要素を1つずつ処理したい場合は、すべてのジェネレータをStreamsにする必要があります。 toStreamをストリームにすることで、以下の例のように開始することができます。

streamStream[String]であり、頭部を評価する必要があります。あなたが熱心に値を計算したくない場合は、ダミーの値を付加し、またはより良い可能性のいずれか、あなたの価値streamlazyします

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 
+0

私の質問を明確にしました。私はzを「ユニット」とするつもりはなかった。今はストリームの最初の2つの要素とそれらを使って 'doSomething'を取るだけですが、3つのプリントが前にあります。 3番目のプリント(「計算」)を行わないようにするにはどうすればよいですか? – Bluu

+0

@Bluu "1"の数字から明らかなように、3つの計算は 'y'の各要素に対して行われます。私が言ったように、頭は常に評価されています。 'stream take 4 foreach println'を試してみると、最初の3回を取ってから2番目のバッチが計算されていることがわかります –

+0

今見ています。ありがとう。そしてhead_の頭を厳密に評価するだけなので、 'List(" foo "、" bar "、" baz ")。toStream'を呼び出す必要があります。あなたはその周りに何か方法を知っていますか? – Bluu

関連する問題