Scala Goodies: Pattern matching with typed lists or Working around Scala's type erasure

Last updated:
Scala Goodies: Pattern matching with typed lists or Working around Scala's type erasure
Source

If you ever try to perform pattern matching on a Generic type (for example, List[Int]), you'll find out that you can't. Not in Scala anyway:

// lets define a list of Ints
val list1:List[Int] = List(1,2,3,4,5,6)

// and then try to pattern match on it
list1 match {
    case list: List[Int] => "It's a list of ints"
    case _ => "List of unknown type"
}
// you'll get an error:
// non-variable type argument Int in type pattern List[Int] (the underlying of List[Int]) is unchecked since it is eliminated by erasure

This is because of something called type erasure.

Due to the way Java code is compiled and run, generic types aren't available at runtime.

Once your Java code is compiled, the Java Runtime does not know it was ever a generic type. So in order to support seamless interoperability with Java, Scala needs to play by the same rules, and this is why you have Type erasure in Scala.

There are a few ways to work around that, it seems (though none are particularly elegant). A simple search on google will show you many results. If you only need to pattern match on Lists that only contain a single type, the following technique may be of use to you.

This particular workaround only works with Lists of a single type

Quick solution

val ints: List[Int] = List(1,2,3,4,5)
val strings: List[String] = List("foo","bar","baz")

ints match{
    case List(_: Int, _*) => "it's a list of ints"
    case List(_: String, _*) => "it's a list of strings" 
}
// "it's a list of ints"

References

Dialogue & Discussion