gpt4 book ai didi

scala - 练习 : implementing Stream in Scala

转载 作者:行者123 更新时间:2023-12-04 05:35:42 27 4
gpt4 key购买 nike

我正在关注这本书 Functional programming in Scala尤其是你实现一个简单的 Stream trait 和伴随对象的部分。作为引用,这是我们迄今为止在伴随对象中的内容

object Stream {
def empty[A]: Stream[A] =
new Stream[A] {
def uncons = None
}

def cons[A](hd: => A, tl: => Stream[A]): Stream[A] =
new Stream[A] {
lazy val uncons = Some((hd, tl))
}

def apply[A](as: A*): Stream[A] =
if (as.isEmpty)
empty
else
cons(as.head, apply(as.tail: _*))
}

以及到目前为止的特征:
trait Stream[A] {
import Stream._

def uncons: Option[(A, Stream[A])]

def toList: List[A] = uncons match {
case None => Nil: List[A]
case Some((a, as)) => a :: as.toList
}

def #::(a: => A) = cons(a, this)

def take(n: Int): Stream[A] =
if (n <= 0)
empty
else (
uncons
map { case (a, as) => a #:: (as take (n - 1)) }
getOrElse empty
)
}

下一个练习要求我为 takeWhile 编写一个实现。我认为以下会做
  def takeWhile(f: A => Boolean): Stream[A] = (
uncons
map { case (a, as) => if (f(a)) (a #:: (as takeWhile f)) else empty }
getOrElse empty
)

不幸的是,似乎我得到了一个无法追踪的方差错误:
error: type mismatch;  found   : Stream[_2] where type _2 <: A 
required: Stream[A]
Note: _2 <: A, but trait Stream is invariant in type A.
You may wish to define A as +A instead. (SLS 4.5)
getOrElse empty
^

我可以添加一个方差注释,但在这样做之前,我想了解这里出了什么问题。有什么建议吗?

最佳答案

这似乎是类型推断的问题,因为如果您明确指定子表达式的类型 uncons map { case (a, as) => if (f(a)) (a #:: (as takeWhile f)) else empty },它就可以工作。 .

def takeWhile(f: A => Boolean): Stream[A] = {
val mapped:Option[Stream[A]] = uncons map {
case (a, as) => if (f(a)) (a #:: (as takeWhile f)) else empty
}
mapped getOrElse empty
}

关于scala - 练习 : implementing Stream in Scala,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11983593/

27 4 0