balteo
balteo

Reputation: 24679

Issue with pattern matching in scala: "error: constructor cannot be instantiated to expected type"

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

Answers (1)

jwvh
jwvh

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

Related Questions