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?
CodePudding user response:
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
CodePudding user response:
Yes, you should swap the orders of the two cases in your sum function.
In Scala, the order of the cases in a match expression is important. The first case that matches the input will be executed, and the subsequent cases will be ignored. Since the mNil case matches every input, the Cons case will never be executed and will always result in a warning that it is unreachable.
By swapping the order of the cases so that Cons comes first, the Cons case will now be executed for any non-empty mList and the sum of the elements will be calculated correctly.