= Solution
Use a shared memoized <lazy list> with a separate mutable cursor in each iterator:
``
import scala.collection.immutable.Stream
class FunIter[T] private (
private var rest: Stream[T]) extends Iter[T] {
def this(v: T, f: T => T) = this(Stream.iterate(v)(f))
def hasNext: Boolean = true
def next(): T = {
val result = rest.head
rest = rest.tail
result
}
def copy(): Iter[T] = new FunIter[T](rest)
}
``
For a total step function, the stream is infinite and its values are $v,f(v),f(f(v)),\ldots$. At every call, `rest` starts with the next unconsumed value. Copying that reference gives a new cursor at exactly the same position; later cursor assignments are independent.
The <memoized iterator snapshot> is useful for the next part: if `f` owns private mutable state, advancing either cursor realizes a previously unknown tail only once, and both copies can then read the same cached values. Merely constructing `new FunIter(current, f)` would share the mutable closure while generating two independent futures, which could diverge. Memoization instead makes the generated sequence shared and the consumption positions independent. The closure must not be mutated externally, and generic element payloads are shared rather than deep-copied. Retaining an old cursor can retain cached cells.<Scala 2.12 Stream API documentation>[Opening memoization example and notes on retained heads]{ref}
Back to article page