I want to return a type from a function. For example:
class Super
case class One(a: Int) extends Super
case class Two(b: Float) extends Super
case class Unknown extends Super
def decide(criterion: String): ??? = {
criterion match {
case "one" => One
case "two" => Two
case _ => Unknown
}
}
So I want to return the type itself, to store it in a Map so that I could apply it somewhere later:
val test = Buffer(
("ahaha" -> "one")
("ohoho" -> "two")
("lalala" -> "one")
)
var map = scala.collection.mutable.Map[String, Super]()
test.map {pair =>
map(pair._1) = decide(pair._2)
}
So that later I could like:
def act(code: String) {
map(code) match {
case One => doSmth[One]()
case Two => doSmth[Two]()
case _ => doNothing()
}
}
I know that some parts, like the unused parameters of the case classes may seem strange here, but this is how it is in the environment I am working in, and this example is that full because I am not sure if it will differ if I take something away...
So how can I make the decide
function return a type and then use it in a manner similar to what I have shown?
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?"
}