Vote count:
0
I am doing some exercises in Scala from the book Functional Programming in Scala [MEAP]. In the chapter of Strictness and laziness I have to implement a zipAll implementation for Stream. Relevant code:
case object Empty extends Stream[Nothing]
case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A]
def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = {
lazy val head = hd
lazy val tail = tl
Cons(() => head, () => tail)
}
def empty[A]: Stream[A] = Empty
def unfold[A, S](z: S)(f: S => Option[(A, S)]): Stream[A] = f(z) match {
case Some((a, s)) => cons(a, unfold(s)(f))
case None => empty
}
The problem is I get a weird type mismatch. The zipAll function should continue the traversal as long as either stream has more elements and it uses Option to indicate whether each stream has been exhausted. The function zipAll has to be implemented via unfold (above). I have the right answer done by the authors of the book, which don't implement straightforward zipAll but use zipWithAll to abstract it. However, my solutions is not abstracted and I would like to know why it doesn't work.
My answer:
def myZipAll[B, C](s2: Stream[B]): Stream[(Option[A], Option[B])] =
unfold((this, s2)){
case (Empty, Empty) => None
case (Cons(h, t), Empty) => Some( ((Some(h()), Option.empty[B]), (t(), empty[B])) )
case (Empty, Cons(h, t)) => Some( ((Option.empty[A], Some(h())), (empty[A], t())) )
case (Cons(h1, t1), Cons(h2, t2)) => Some( ( (Some(h1()), Some(h2())), (t1(), t2())) )
}
Author's solution (it works):
def zipWithAll[B, C](s2: Stream[B])(f: (Option[A], Option[B]) => C): Stream[C] =
unfold((this, s2)){
case (Empty, Empty) => None
case (Cons(h, t), Empty) => Some( (f(Some(h()), Option.empty[B]), (t(), empty[B])) )
case (Empty, Cons(h, t)) => Some( (f(Option.empty[A], Some(h())), (empty[A], t())) )
case (Cons(h1, t1), Cons(h2, t2)) => Some( ( f(Some(h1()), Some(h2())), (t1(), t2())) )
}
def zipAll[B](s2: Stream[B]): Stream[(Option[A], Option[B])] =
zipWithAll(s2)((_, _))
Error message from Intellij says: "Expression of type Stream[(Any, Any)]" doesn't conform to expected type Stream[(Option[A], Option[B])].
Weird type mismatch in zipAll implementation in Scala
Aucun commentaire:
Enregistrer un commentaire