Yes it will be possible to construct what you're after—whether or not my answers are actually correct. :)
In my first example I flatMapped when I should have mapped. My Haskell to Scala translation skills are rather weak, having never programmed in Haskell.
def i1[E1,E2]: Iteratee[E1, Iteratee[E2, (Option[E1], Option[E2])]] = {
Iteratee.head[E1].map(e1 => Iteratee.head[E2].map(e2 => (e1, e2)))
}
Example usage:
val i1 = Iteratee.i1[Int, String]
val res = (Enumerator(1, 2, 3, 4) |>>> i1).flatMap(i2 => Enumerator("5", "6", "7", "8") |>>> i2)
Await.result(res, Duration.Inf) must equalTo((Some(1), Some("5")))
One of the differences is that Play's iteratees are asynchronous and make extensive use of futures. The |>>> operation returns its result in a future so we need to flatMap the result of the first iteration together with the second. We also need to await the result of the second iteration at the end.
Cheers
Rich