Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to rewrite a for-loop Seq output into Stream output?

Tags:

stream

scala

I have tried to convert this Scala function to return a lazy Stream instead of eagerly retrieve all the results and convert them from a Seq to Stream when all the results are present. I have feeling the issue lies in (for (i <- 1 to 9; z <- solve(xs.updated(pos, i), pos)) yield z) toStream.

Any advice is appreciated. Another solution I am looking at is to return a result when it is found. With this solution I probably have only 1 result returned. Thanks

isConflictAt(xs.updated(pos, 0), pos, xs(pos) is a constraint check function.

  def solve(xs : List[Int], pos: Int): Stream[List[Int]] = {
    if (!isConflictAt(xs.updated(pos, 0), pos, xs(pos))) {
      val pos = xs.indexOf(0)
      if (pos < 0) {println(xs); Stream(xs) } else (for (i <- 1 to 9; z <- solve(xs.updated(pos, i), pos)) yield z) toStream
    } else Stream.empty
  }
like image 504
thlim Avatar asked Apr 04 '13 10:04

thlim


1 Answers

for (i <- 1 to 9; z <- solve(???)) yield z means (1 to 9).flatMap{i => solve(???)}. See this answer.

To generate lazy result you should make the source (1 to 9) lazy using (1 to 9).view or (1 to 9).toStream.

Try this:

scala> def solve(pos: Int): Stream[List[Int]] = {
     |   println(pos)
     |   Stream.fill(3)((1 to pos).map{ _ => util.Random.nextInt}.toList)
     | }
solve: (pos: Int)Stream[List[Int]]

scala> for{
     |   i <- (1 to 9).toStream
     |   z <- solve(i)
     | } yield z
1
res1: scala.collection.immutable.Stream[List[Int]] = Stream(List(-1400889479), ?)

scala> res1.force
2
3
4
5
6
7
8
9
like image 136
senia Avatar answered Oct 17 '22 05:10

senia