samedi 30 août 2014

Weird type mismatch in zipAll implementation in Scala


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])].



asked 1 min ago







Weird type mismatch in zipAll implementation in Scala

Aucun commentaire:

Enregistrer un commentaire