Reputation: 24679
I am trying to define a toList
method inside a trait as follows:
sealed trait Stream[+A] {
def toList: List[A] = this match {
case Empty => List()
case Cons(h, t) => h()::t().toList()
}
}
case object Empty extends Stream[Nothing]
case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A]
object Stream {
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 apply[A](as: A*): Stream[A] =
if (as.isEmpty) empty else cons(as.head, apply(as.tail: _*))
}
I get the following compilation error:
stream.scala:16: error: pattern type is incompatible with expected type;
found : Empty.type
required: Stream[A]
case Empty => List()
^
stream.scala:17: error: constructor cannot be instantiated to expected type;
found : Cons[A(in class Cons)]
required: Stream[A(in trait Stream)]
case Cons(h, t) => h()::t().toList()
^
Can someone please advise?
Upvotes: 1
Views: 226
Reputation: 51271
The errors you are seeing come from the REPL. Every complete statement in the REPL is packaged in an object so that it can produce and report intermediate values: res0
, res1
, etc.
When you :load
the file it is as if you had typed each line separately, but if you copy/paste, :pa
, the code into the REPL it works (after you fix the ()
problem).
Another option is to wrap all the code into an outer object
. Then when you :load
the file it will be compiled as a unit instead of as separate objects and classes.
Upvotes: 3