George
George

Reputation: 51

Scala Streams: Self-Reference, Function Calls and Lazy Evaluation

I'm trying to understand why the following code using Scala Streams doesn't work:

def main(args: Array[String]): Unit = {
  lazy val y : SimNumericStream = y.shift
  y.scalstream.take(10).print
}

class SimNumericStream( ss : Stream[Double] )  {  
  lazy val scalstream = ss
  lazy val shift = new SimNumericStream( 0 #:: scalstream )
}

and yet replacing

lazy val y : SimNumericStream = y.shift 

by

lazy val y : SimNumericStream = new SimNumericStream( 0 #:: y.scalstream )

works just fine.

I'm looking for a solution that allows to me wrap up operations on Streams inside functions without breaking the lazy evaluation when the streams are self-referential.

Upvotes: 1

Views: 518

Answers (2)

George
George

Reputation: 51

I have achieved the effect I would like through the following:

  class SimNumericStream(str: =>Stream[Double]) {
    def ::(hd: Double) = Stream.cons(hd, str)
    def shift = 0.0 :: this
  }
  implicit def streamToSimNumericStream(str: =>Stream[Double]) = new SimNumericStream(str)

  lazy val y: Stream[Double] = y.shift

Upvotes: 0

Luigi Plinge
Luigi Plinge

Reputation: 51099

In your first version, your call to instantiate SimNumericStream is inside an instance of SimNumericStream, so you can never actually intantiate one unless you have one already.

Upvotes: 4

Related Questions