Scala中zipAll实现中奇怪的类型不匹配

Scala中zipAll实现中奇怪的类型不匹配,scala,types,intellij-idea,mismatch,any,Scala,Types,Intellij Idea,Mismatch,Any,我正在用Scala[MEAP]中的函数编程一书中的Scala做一些练习。在“严格和懒惰”一章中,我必须为Stream实现zipAll实现。相关代码: 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]

我正在用Scala[MEAP]中的函数编程一书中的Scala做一些练习。在“严格和懒惰”一章中,我必须为Stream实现zipAll实现。相关代码:

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
} 
问题是我有一个奇怪的类型不匹配。zipAll函数应该继续遍历,只要其中一个流有更多的元素,并且它使用选项指示每个流是否已耗尽。zipAll功能必须通过展开(如上)实现。这本书的作者给出了正确的答案,他们没有实现简单的ZipPall,而是使用zipWithAll来抽象它。然而,我的解决方案不是抽象的,我想知道为什么它不起作用

我的答覆是:

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())) )
  }
作者的解决方案(有效):


Intellij的错误消息说:“类型流[(Any,Any)]的表达式”不符合预期的类型流[(选项[A],选项[B])。

您的解决方案在命令行中对我有效,因此可能是Intellij错误。当您看到这种类型的错误时,编译器所做的类型推断无论出于何种原因都会失败,因此您会得到“Any”。我的解决方案和您的一样,但在您使用Option.empty[A]和Option.empty[B]的地方,我没有使用任何解决方案。试试看。

当时肯定是IntelliJ的bug,因为
myZipAll
今天在IntelliJ中没有显示任何错误。
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)((_, _))