练习:在Scala中实现流
我在学习《Scala中的函数式编程》(Functional programming in Scala),特别是在实现一个简单的流特征和伴生对象的部分。作为参考,以下是我们到目前为止在obejct配套文件中的内容练习:在Scala中实现流,scala,functional-programming,Scala,Functional Programming,我在学习《Scala中的函数式编程》(Functional programming in Scala),特别是在实现一个简单的流特征和伴生对象的部分。作为参考,以下是我们到目前为止在obejct配套文件中的内容 object Stream { def empty[A]: Stream[A] = new Stream[A] { def uncons = None } def cons[A](hd: => A, tl: => Stream[A]):
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
)
}
不幸的是,我似乎得到了一个我无法追踪的方差错误:
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
^
错误:类型不匹配;found:Stream[_2]where type _2这似乎是类型推断的问题,因为如果显式指定子表达式的类型uncon 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
}
要完成另一个答案,请在这一行中输入空值
:
map { case (a, as) => if (f(a)) (a #:: (as takeWhile f)) else empty }
被推断为empty[Nothing]
,这意味着(a#::(as takeWhile f))或者empty
被推断为Stream[Foo谢谢,这是有效的。你知道类型推断器在这种情况下失败的原因吗?在Scala中必须键入中间值是常见的吗(当然,除了像Nil:List[Int]
这样模棱两可的情况)我不知道为什么它会失败,但这并不常见。尽管有一些已知的限制,例如递归函数或多重返回。也许你应该在邮件列表中询问这个问题。
map { case (a, as) => if (f(a)) (a #:: (as takeWhile f)) else empty }
map { case (a, as) => if (f(a)) (a #:: (as takeWhile f)) else empty[A] }