This post originated from an RSS feed registered with Scala Buzz
by Daniel Sobral.
Original Post: Pattern matching on abstract types with Scala 2.10.0
Feed Title: Algorithmically challenged
Feed URL: http://dcsobral.blogspot.com/feeds/posts/default
Feed Description: Random thoughts of an IT worker in the stone age of computer science.
Scala 2.10.0 is out, and one of its greatest improvements is a completely new pattern matching algorithm on the compiler. That algorithm fixes lots of bugs that have existed all the way up to 2.9.x and adds more and better static checks.
One interesting thing that has probably gone unnoticed by most, however, is that it can do more than what the old pattern matcher did, in at least one respect: it can match against abstract types, provides a ClassTag.
To understand that better, consider this REPL session on Scala 2.9.2:
scala> def f[T: ClassManifest](l: List[Any]) = l collect { | case x: T => x | } <console>:8: warning: abstract type T in type pattern T is unchecked sin ce it is eliminated by erasure case x: T => x ^ f: [T](l: List[Any])(implicit evidence$1: ClassManifest[T])List[T]
scala> def f[T: ClassTag](l: List[Any]) = l collect { | case x: T => x | } f: [T](l: List[Any])(implicit evidence$1: scala.reflect.ClassTag[T])List [T]
scala> f[Int](List(1, 2.0, "three")) // It can't find Int because they are boxed res0: List[Int] = List()
scala> f[String](List(1, 2.0, "three")) // But AnyRefs are ok res1: List[String] = List(three)
Note that it doesn't reify types -- that is, it can't tell whether your List[Any] is a List[String], but it does go a bit further than what was possible before.