We use at our company a data structure that looks like that:
trait Resource
case class templatedResource[T](t: T) extends Resource
case class BParameter()
case class CParameter()
object B {
type Resource = templatedResource[BParameter]
}
object C {
type Resource = templatedResource[CParameter]
}
At some point, given some unknown Resource
s we want to use pattern matching to determine their inner types and launch some different processings.
But due to Type Erasure, simple pattern matching doesn't work. So we have tried to use TypeTags
, but without success :
import scala.reflect.runtime.universe._
object Service {
def process(resource: Resource)(implicit tag: WeakTypeTag[Resource]) = {
(tag.tpe, resource) match {
case (t, b: B.Resource) if t =:= typeOf[B.Resource] =>
println("b !!")
case (t, c: C.Resource) if t =:= typeOf[C.Resource] =>
println("c !!")
case _ =>
throw new IllegalStateException(s"Unexpected resource type")
}
}
}
val bParam = BParameter()
val bResource: B.Resource = templatedResource(bParam)
Service.process(bResource)
// throws java.lang.IllegalStateException: Unexpected resource type
// at Service$.process(<console>:26)
It seems that the t =:= typeOf[B.Resource]
are always false because t
only knows the Resource
trait ( t =:= typeOf[Resource]
) and not the concrete implementation.
How can I get this pattern matching to work ?
Aucun commentaire:
Enregistrer un commentaire