2012-03-24 46 views
0

我有一個深深的「嵌套」的理解,簡化到3層以下:x,y和z。我希望做只有X A 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個打印證明。我只想計算前兩個,因爲這些都是我從流中提取的。我可以通過在第二個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的頭被評估。

你是對的,如果你只希望逐個處理每個結果元素,那麼所有的生成器都必須是流。如下例所示,您可以通過讓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是'單位'。現在有3個打印前面,即使我只採取流的前2個元素和'doSomething'。我如何使第三次打印(「計算」)不會發生? – Bluu 2012-03-24 06:32:07

+0

@Bluu這三個計算是針對'y'的每個元素,應該從「1」數字中清楚。就像我說的,頭部總是被評估。嘗試'流4取foreach println',你會看到,第二批只計算前3後採取 – 2012-03-24 06:39:17

+0

我現在看到。謝謝。爲了嚴格評估head_的頭部,這就是爲什麼我需要調用List(「foo」,「bar」,「baz」)。toStream'。你知道有什麼方法嗎? – Bluu 2012-03-24 18:08:58