Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

can't match against case object

Trying to implement a super simple count method for a linked list, but when I try to match the pattern of my case object I get an error.

Here's the code:

trait LinkedList[+A] {
  def count = 0
}

case object Leaf extends LinkedList[Nothing]

case class  Node[A](head: A, tail: LinkedList[A]) extends LinkedList[A] {
  override def count: Int = this match {
    case Node(_, t) => 1 + t.count
    case Leaf => 0
  }
}

Here's the error:

scala> :load LinkedList.scala
Loading LinkedList.scala...
defined trait LinkedList
defined module Leaf
<console>:17: error: pattern type is incompatible with expected type;
 found   : Leaf.type
 required: Node[A]
Note: if you intended to match against the class, try `case _: <none>`
           case Leaf => 0
                ^

What I don't understand, is that I've always matched case objects like this, but now it doesn't work for some reason... How do I fix this?

like image 734
Electric Coffee Avatar asked Apr 27 '26 20:04

Electric Coffee


1 Answers

It's because you are matching this, which is a Node. A Leaf is not a Node, so this can never be a Leaf. The compiler is basically telling you that the Leaf case is never going to happen, so you probably have a bug.

To fix the bug, delete that case. You don't need it anyway since the leaf case is handled by the default count method defined on the trait. This means that the method should be reduced to the more intuitive:

override def count: Int = 1 + tail.count

Or move the count method up to the trait:

trait LinkedList[+A] {
  def count: Int = this match {
    case Node(_, t) => 1 + t.count
    case Leaf => 0
  }
}
like image 148
dhg Avatar answered Apr 29 '26 12:04

dhg