Let's suppose we have a generic class Container
:
case class Container[+A](value: A)
We then want to pattern match a Container
with a Double
and a Container
of Any
:
val double = Container(3.3)
var container: Container[Any] = double
To do this, we would normally write:
container match {
case c: Container[String] => println(c.value.toUpperCase)
case c: Container[Double] => println(math.sqrt(c.value))
case _ => println("_")
}
However, the compiler gives two warnings, one for each of the first two cases. For example, the first warning says: "non-variable type argument String in type pattern Container[String] is unchecked since it is eliminated by erasure". Because of the erasure, it is impossible during runtime to distinguish between different kinds of containers and the first catch will be matched. As a consequence, container of type Container[Double]
will be matched by the first case, which catches Container[String]
objects, so toUpperCase
method will be called on a Double
and a java.lang.ClassCastException
will be thrown.
How to match a Container
parametrized by a particular type?