Stream
(or LazyList
, or even an Iterator
).to
method but the following does not terminate (I guess than the underlying Collector tries to collect all the elements of the stream)fs2.Stream.constant(1).compile.to(Stream)
Stream[F, A] => Iterator
has its complexity as well, but here the stream is pure
@nicmart
Completely untested (so probably buggy), and does not generalise to effectful streams along several directions, but try this
def toIter[A](s: Stream[Pure, A]): Iterator[A] = {
sealed trait State {
def hasNext: (State, Boolean) = this match {
case Idle(s) =>
s.pull.uncons1
.flatMap(Pull.output1)
.stream
.compile
.last
.flatten match {
case Some((a, next)) => Pulled(a, next) -> true
case None => Exhausted -> false
}
case s @ Pulled(_, _) => s -> true
case s @ Exhausted => s -> false
}
def next: (State, Option[A]) = this match {
case Idle(_) => hasNext._1.next
case Pulled(a, tail) => Idle(tail) -> a.some
case s @ Exhausted => s -> None
}
}
case class Idle(stream: Stream[Pure, A]) extends State
case class Pulled(a: A, tail: Stream[Pure, A]) extends State
case object Exhausted extends State
new Iterator[A] {
var state: State = Idle(s)
def hasNext = {
val (ns, r) = state.hasNext
state = ns
r
}
def next = {
val (ns, r) = state.next
state = ns
r.getOrElse(throw new Exception("Exhausted"))
}
}
}