lerp90
lerp90

Reputation: 531

Type mismatch using pattern matching on constructors scala

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

Answers (1)

jwvh
jwvh

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

Related Questions