Reputation: 531
I'm trying to define a HKT in Scala (a generic stream) and I'm not sure why I'm getting a type mismatch error while trying to implement the exists method:
Here's my code so far
sealed trait SmartStream[+A]
case object Nil extends SmartStream[Nothing]
case class Cons[+A](h : () => A, t : () => SmartStream[A]) extends SmartStream[A]
object SmartStream {
def nil[A] : SmartStream[A] = Nil
def cons[A](h : => A, t : => SmartStream[A]) : SmartStream[A] = {
lazy val g = h
lazy val u = t
Cons(() => g, () => u)
}
def apply[A](as: A*) : SmartStream[A] = {
if (as.isEmpty) nil
else cons( as.head, apply(as.tail: _*))
}
def exists[A](p : A => Boolean) : Boolean = {
this match {
case Nil => false
case Cons(h, t) => p(h()) || t().exists(p)
}
}
}
The error I'm getting is:
ScalaFiddle.scala:21: error: pattern type is incompatible with expected type;
found : ScalaFiddle.this.Nil.type
required: ScalaFiddle.this.SmartStream.type
case Nil => false
^
ScalaFiddle.scala:22: error: constructor cannot be instantiated to expected type;
found : ScalaFiddle.this.Cons[A]
required: ScalaFiddle.this.SmartStream.type
case Cons(h, t) => p(h()) || t().exists(p)
^
Thanks in advance!
Upvotes: 0
Views: 72
Reputation: 51271
You're putting exists()
in the SmartStream
object (i.e. singleton). That means this
is type SmartStream.type
and can never be anything else.
If you move exists()
to the trait, and remove the type parameter, things will compile.
sealed trait SmartStream[+A] {
def exists(p : A => Boolean) : Boolean = {
this match {
case Nil => false
case Cons(h, t) => p(h()) || t().exists(p)
}
}
}
There may be other deficiencies in the design, but at least this compiles.
Upvotes: 3