views:

202

answers:

2
scala> class A
defined class A

scala> class B
defined class B

scala> val a: A = new A
a: A = A@551510e8

scala> a match {
     | case _: B => println("unlikely")
     | case _ => println("no match")
     | }
no match

In the example above shouldn't the compiler tell me that one of the cases can never match? A slightly more complicated example recently caught me out, leading to what felt like an unnecessary bug that should have been caught by the compiler.

Edit:

Just to be clearer about the question. Is this impossible in Scala for some reason I can't see? (I can understand if the types were using generics and type erasure was causing problems but this looks pretty straight forward.) And if this is not impossible are there legitimate reasons this isn't in Scala? If not when will it be added? ;)

+4  A: 

The compiler does warn you (in fact compilation fails) if you use case classes:

scala> case class A()
defined class A

scala> case class B()
defined class B

scala> val a = A()
a: A = A()

scala> a match {
     | case A() => println("A")
     | case B() => println("B")
     | case _ => println("_")
     | }
<console>:13: error: constructor cannot be instantiated to expected type;
 found   : B
 required: A
       case B() => println("B")
michid
Unfortunately case classes have some restrictions and aren't always suitable. I can't see why the compiler can't figure this out for normal classes too.
Dave
+12  A: 

Currently, exhaustiveness and redundancy checking are only done for case class constructor patterns. In principle, the compiler could do this for some other kinds of patterns, too. But it would have to be specified in the SLS exactly what tests are done. This looks doable but non-trivial, given the interactions between different pattern classes. So, in summary, that's one of the areas in Scala that would profit from further contributions.

Martin Odersky
Amazing ! I go my answer from the one who teached me scala and indvented it too ! Thx stackoverflow !
Kami