I think you may want case object One
, etc, rather than using Class or ClassTag. Then you get useful match support. For the act
method, your case objects could return a ClassTag or similar, or just let act associate One with doSmth[OneClass] etc.
It seems you can make your case companions into case objects. Isn't that special.
package typeswitch
import reflect.runtime.universe._
sealed trait Selection
class Super
case class One(a: Int) extends Super
case object One extends Selection
case class Two(b: Float) extends Super
case object Two extends Selection
case class Unknown() extends Super
case object Unknown extends Selection
object Test extends App {
type What = Selection
def decide(criterion: String): What = criterion match {
case "one" => One
case "two" => Two
case _ => Unknown
}
val test = List(
"ahaha" -> "one",
"ohoho" -> "two",
"lalala" -> "one"
)
val m = scala.collection.mutable.Map[String, What]()
test map (pair => m(pair._1) = decide(pair._2))
def act(code: String) = m(code) match {
case One => doSmth[One]()
// non-exhaustive
//case Two => doSmth[Two]()
case Unknown => doNothing()
// handle exhaustively
case s: Selection => doSmthNew(s)
}
def doSmthElse[A <: Super]()(implicit t: TypeTag[A]): A = {
Console println s"Do st with $t"
val claas: Class[_] = t.mirror.runtimeClass(t.tpe)
null.asInstanceOf[A]
}
def doSmth[A <: Super]()(implicit t: ClassTag[A]): A = {
Console println s"Do st with $t"
val claas: Class[_] = t.runtimeClass
null.asInstanceOf[A]
}
def doSmthNew[A >: What : ClassTag, B <: Super](what: A): B = {
Console println s"Do st new with $what"
null.asInstanceOf[B]
}
def doNothing() { }
val res = act("lalala")
Console println s"Got $res?"
}