Knows Not Much Knows Not Much - 3 months ago 12
Scala Question

Scala Stream processing

I wrote the following code in scala using streams

def foo(x: Int) : Stream[Int] = {println("came inside"); (2 * x)} #:: foo(x + 1)
foo(1).takeWhile(_ < 6).toList.foreach(x => println(s"+++ $x"))


This works and produces the following output

came inside
came inside
came inside
+++ 2
+++ 4


but I wanted the processing to happen like

came inside
+++ 2
came inside
+++ 4
came inside


Basically I want to process one by one, till the termination condition of < 6 is met. I guess its my "tolist" method which first creates a giant list and only then processes it.

Answer

First, format your code in a more readable fashion. Then, remove the toList: all it does is pull your entire stream into a single variable. Doing this forces all the values to be calculated. Since every value is calculated at this point, we know that the 'inside' printlns will execute before the 'outside' ones do. You want to store the definition of your function (including it's starting value) as a lazily evaluated value. This should work:

def river(x: Int) : Stream[Int] = {
  println("Inside function.")
  (2 * x) #:: river(x + 1)
}

lazy val creek = river(1)
creek.takeWhile(_ < 6).foreach(x => println(s"+++ $x"))