You can use the self-running thread trick:
def randSeq(n: Int): Stream[Int] = { // an infinite stream of random numbers val s = Stream.continually{ Random.nextInt(10) } s.zip(s.tail) // pair each number with it sucessor .filter((pair) => pair._1 != pair._2) // filter out equal pairs .map(_._1) // break pairs again .take(n); // take first n }
Then you can filter consecutive equal elements and finally take the desired amount.
Update: Yes, it will work. Suppose you have [1,2,2,2,3,...] . Its completion will lead to [(1,2),(2,2),(2,2),(2,3),(3,..),...] , filtering creates [(1,2),(2,3),(3,..),...] , so the final result is [1,2,3,...] .
We can even prove this: after pairing, the sequence has the following property: a(i)._2 = a(i+1)._1 . This property is saved during the filtering phase. The filtering step also provides a(i)._1 != a(i)._2 . Putting it together, we get a(i)._1 != a(i)._2 = a(i+1)._1 so really a(i)._1 != a(i+1)._1 .
The problem with your approach using fold is that you are creating a bottom-up stream in your fold function. This means that to evaluate the stream header, you need to evaluate an endless sequence of operations :+ , although the head remains unchanged. The correct flow should be built from top to bottom - calculate its head and postpone the calculation of the rest in the tail. For instance:
def randSeq1(n: Int): Stream[Int] = { def g(s: Stream[Int]): Stream[Int] = s match { case h
Here we first radiate the head and set aside the rest of the calculation on a lazily priced tail.