Consider the following broken function:
def sum (list : Seq[Int]) : Int = list match {
case Nil => 0
case head :: tail => head + sum(tail)
}
Here, the function was supposed to work with a List[Int]
, but was refactored to accept Seq[Int]
instead, thus becoming broken without the compiler noticing.
This gaping hole in Scala's incomplete pattern match detection makes it next to useless.
I want to have a way of systematically detecting such problems. Specifically, I'd like the compiler to emit an error/warning on every instanceof
-guided pattern match, i.e. I only want to allow pattern matches on sealed hierarchies and on custom matchers.
Are there existing compiler options/plugins for doing conservative (as opposed to arbitrary) checks of pattern matching safety?
Nil
and::
are clearly ways to construct aList
, but not allSeq
uences happen to beLists
, so one would expect the Scala type checker to reject this program as ill-typed. Right?Wrong. Try this and you'll see what I mean:
So you see, some
Seq
uences might be able to be deconstructed withNil
and::
, so those which can, will. Those which can't will fail the pattern match and move on, trying the next match.Nil
and::
are sufficient to cover all the possibilities forList
, but not forSeq
. There is a tradeoff here between subtyping, convenience, and type safety. The solution for now is: be more careful when you refactor.