Skip to content

Instantly share code, notes, and snippets.

@chris-zen
Last active February 10, 2016 16:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chris-zen/c1b33085ea442cdbbe2b to your computer and use it in GitHub Desktop.
Save chris-zen/c1b33085ea442cdbbe2b to your computer and use it in GitHub Desktop.
Way to match type patterns using reflection with Scala 2.10+ and performance comparison with plain casting
// Adapted to Scala 2.10+ from
//
// http://daily-scala.blogspot.ie/2010/01/overcoming-type-erasure-in-matching-1.html
//
import scala.reflect.runtime.universe._
class Def[C](implicit desired: TypeTag[C]) {
def unapply[X](c: X)(implicit m: TypeTag[X]): Option[C] = {
def sameArgs = desired.tpe.typeArgs.zip(m.tpe.typeArgs).forall { case (desired, actual) => actual <:< desired }
if (m.tpe <:< desired.tpe && sameArgs)
Some(c.asInstanceOf[C])
else
None
}
}
val MapFromString = new Def[collection.Map[String, _]]
val m = Map("1" -> 1)
def ptime[F](f: => F) = {
var t0 = System.nanoTime
val ans = f
printf("Elapsed: %.3f s\n",1e-9*(System.nanoTime-t0))
ans
}
ptime(1 to 100000 map { i =>
m match {
case MapFromString(x) => x.get(i.toString)
// When IntelliJ complains about the previos line, even when the compiler doesn't, you can use the following line
// case MapFromString(x: Map[String, _]) => x.get(i.toString)
}
})
// Elapsed: 4.833 s
ptime(1 to 100000 map { i =>
m match {
case x: Map[_, _] => x.asInstanceOf[Map[String, _]].get(i.toString)
}
})
// Elapsed: 0.021 s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment