1

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.

1
  • i) You're defining a stream with side-effects (i.e. println), which is hard to deal with and difficult to reason about. ii) Yes, toList will "materialize the stream", and so it will trigger all side-effects, before executing whatever you call afterwards. Commented Aug 24, 2016 at 23:02

1 Answer 1

1

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"))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.