scalapattern-matchingalgebraic-data-types

scala Does match end in Nil?


I'm new in Scala and I'm reading fp in Scala. There is an example code in this book and I type this into Idea:

sealed trait mList[+A]
case object mNil extends mList[Nothing]
case class Cons[+A] (head:A, tail:mList[A]) extends mList[A]

object mList {
  def sum(ints: mList[Int] ): Int = ints match {
    case mNil => 0
    case Cons(h, t) => h + sum(t)
  }

  def apply[A](as: A*): mList[A] =
    if (as.isEmpty) mNil
    else Cons(as.head, apply(as.tail:_*))
}

Then I get a warning from Idea that case Cons(h, t) is unreachable.

I'm sure in this book case Nil comes before case Cons. But when I run the code this way I always get sum=0.

So should I swap the orders of the two cases?


Solution

  • You could swap the cases but actually this is not necessary.

    You are missing backticks if you'd like to refer to the object (or another existing variable)

    def sum(ints: mList[Int]): Int = ints match {
      case `mNil` => 0
      case Cons(h, t) => h + sum(t)
    }
    

    Otherwise without backticks mNil (lower-case) is a new-variable pattern like in case x => ... i.e. it matches everything.

    Alternatively you could call the object in upper case. Then you don't need backticks

    case object MNil extends mList[Nothing]
    
    def sum(ints: mList[Int]): Int = ints match {
      case MNil => 0
      case Cons(h, t) => h + sum(t)
    }
    

    what is the use back ticks in scala

    Need clarification on Scala literal identifiers (backticks)

    Why does pattern matching in Scala not work with variables?

    Pattern matching on non-literal values