Better type checking on match in Scala
Asked Answered
T

3

10
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? ;)

Turbo answered 2/8, 2010 at 13:22 Comment(0)
U
23

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.

Unformed answered 2/8, 2010 at 15:50 Comment(1)
Amazing ! I go my answer from the one who teached me scala and indvented it too ! Thx stackoverflow !Frasco
S
4

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")
Spacious answered 2/8, 2010 at 14:6 Comment(1)
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.Turbo
P
1

I checked in Scala 2.13.3, we get a warning of fruitless type test:

scala> a match {
     | case _:B => println("B")
     | case _ => println("no match")
     | }
       case _:B => println("B")
              ^
On line 2: warning: fruitless type test: a value of type A cannot also be a B
no match
Phrase answered 13/2, 2021 at 15:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.