I edited the code below because, in my opinion, I incorrectly mapped IterV objects on top of the problem iter.next.
I am experimenting with Iterateein scalaz, and I wonder why the following does not work. Here is what I have:
import scalaz._
import Scalaz._
import IterV._
implicit val iteratorEnumerator = new Enumerator[Iterator] {
def apply[E,A](iter: Iterator[E], i: IterV[E,A]): IterV[E,A] =
if (iter.isEmpty) i
else i.fold(done = (acc,input) => i,
cont = k => apply(iter, k(El(iter.next))))
}
def peekpeek[E]: IterV[E, (Option[E],Option[E])] =
for (a <- peek; b <- peek) yield (a,b)
def peekheadpeek[E]: IterV[E, (Option[E],Option[E],Option[E])] =
for (a <- peek; b <- head; c <- peek) yield (a,b,c)
peekpeek(Iterator(1,2,3,4)).run
peekheadpeek(Iterator(1,2,3,4)).run
This returns:
res0: (Option[Int], Option[Int]) = (Some(1),Some(2))
res1: (Option[Int], Option[Int], Option[Int]) = (Some(1),Some(2),Some(3))
Where did I expect (Some(1),Some(1))and (Some(1),Some(1),Some(2)).
I suspect this is due to what iter.nextis a side effect. What is the best way to handle this?
For comparison, this is taken directly from the source code examples from scalaz . The website is working correctly:
implicit val StreamEnumerator = new Enumerator[Stream] {
def apply[E, A](e: Stream[E], i: IterV[E, A]): IterV[E, A] = e match {
case Stream() => i
case x #:: xs => i.fold(done = (_, _) => i,
cont = k => apply(xs, k(El(x))))
}
}