I have a deeply “nested” for-comprehension, simplified to 3 levels below: x, y, and z. I was hoping making only x a Stream would make the y and z computations lazy too:
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)
But this computes all 3 elements, as evidenced by the 3 prints. I’d like to only compute the first 2, since those are all I take from the stream. I can work around this by calling toStream on the second List and so on. Is there a better way than calling that at every level of the for-comprehension?
What it prints is:
The head of a
Streamis always strictly evaluated, which is why you seeProcessed 1fooetc and notProcessed 2fooetc. This is printed when you create the Stream, or more precisely, when the head ofstreamis evaluated.You are correct that if you only wish to process each resulting element one by one then all the generators will have to be Streams. You could get around calling
toStreamby making them Streams to start with as in example below.streamis aStream[String]and its head needs to be evaluated. If you don’t want to calculate a value eagerly, you could either prepend a dummy value, or better, make your valuestreamlazy:This does not do any “processing” until you take each value: