I am trying to create a "lazy" map of objects (actually, they are actors, but I am asking my question with a more trivial example).
Scala views are, in a sense, lazy. But their laziness is really just non-strictness. That's to say, the values are effectively call-by-name, which is in turn to say that the values are evaluated, when required, by invoking a Function0 (a no-parameter function).
What I'm interested in is a collection that is evaluated lazily, but is evaluated only once. Here's the kind of thing I'm looking for:
val x = Map(1->2, 2->2).view
val y = x map {case (k,v) => (k,{println("Hello");v.toString})}
val z1 = y.find{case (k,_) => k==1}
val z2 = y.find{case (k,_) => k==1}
When I put this into a Scala worksheet, what I get is:
x: scala.collection.IterableView[(Int, Int),scala.collection.immutable.Map[Int,Int]] = IterableView(...)
y: scala.collection.IterableView[(Int, String),Iterable[_]] = IterableViewM(...)
Hello
z1: Option[(Int, String)] = Some((1,1))
Hello
z2: Option[(Int, String)] = Some((1,1))
Everything is just as it should be. Except that I don't want to see that second "Hello". In other words, I only want the mapped function (toString) to be invoked once -- when needed.
Does anyone have a suggestion of how to achieve my goal? It's not super-important but I'm curious if it can be done.
z1andz2? - vvg