0

I want to produce a lazy list of partial sums and stop when I have found a "suitable" sum. For example, I want to do something like the following:

val str = Stream.continually { val i = Random.nextInt println("generated " + i) List(i) } str .take(5) .scanLeft(List[Int]())(_ ++ _) .find(l => !l.forall(_ > 0)) 

This produces output like the following:

generated -354822103 generated 1841977627 z: Option[List[Int]] = Some(List(-354822103)) 

This is nice because I've avoided producing the entire list of lists before finding a suitable list. However, it's suboptimal because I generated one extra random number that I don't need (i.e., the second, positive number in this test run). I know I can hand code a solution to do what I want, but is there a way to use the core scala collection library to achieve this result without writing my own recursion?

The above example is just a toy, but the real application involves heavy-duty network traffic for each "retry" as I build up a map until the map is "complete".

EDIT: Note that even substituting take(1) for find(...) results in the generation of a random number even though the returned value List() does not depend on the number. Does anyone know why the number is being generated in this case? I would think scanLeft does not need to fetch an element of the iterable receiving the call to scanLeft in this case.

3
  • Isn't this caused by because the head is not lazy in Scala streams? (For example: stackoverflow.com/questions/13410659/…) I think Scalaz has lazy streams for this purpose. Commented Nov 17, 2014 at 20:23
  • Is the Stream provided as input, or are you generating random numbers as you go? If the latter, then why not create a recursion that generates a random number with each iteration, checks the sum and runs another iteration if needed? Commented Nov 17, 2014 at 20:36
  • @benji, I could do this, but I was hoping to have a solution that is built purely from the existing abstractions in the standard scala libraries. Commented Nov 17, 2014 at 21:21

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.