Reputation: 9225
scala> val s = for(i <- (1 to 10).toStream) yield { println(i); i }
1
s: scala.collection.immutable.Stream[Int] = Stream(1, ?)
scala> s.take(8).toList
2
3
4
5
6
7
8
res15: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8)
scala> s.take(8).toList
res16: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8)
Looks like Scala is storing stream values in memory to optimize access. Which means that Stream
can't be used as a substitute for imperative loop as it will allocate memory. Things like (for(i <- (1 to 1000000).toStream, j <- (1 to 1000000).toStream) yield ...).reduceLeft(...)
will fail because of memory. Was it wrong idea to use streams this way?
Upvotes: 2
Views: 242
Reputation: 167891
You should use Iterator
instead of Stream
if you want a loop-like collection construct. Stream
is specifically for when you want to store past results. If you don't, then, for instance:
scala> Iterator.from(1).map(x => x*x).take(10).sum
res23: Int = 385
Methods continually
, iterate
, and tabulate
are among the more useful ones in this regard (in the Iterator
companion object).
Upvotes: 5