Reputation: 13
This piece of code does not compile, I'm getting the following errors:
Expression of type MessageA doesn't conform to expected type T
Expression of type MessageB doesn't conform to expected type T
import scala.reflect.runtime.universe._
abstract class BaseMessage
case class MessageA(x : String = "aaa") extends BaseMessage
case class MessageB(y : String = "bbbb") extends BaseMessage
val TypeA = typeTag[MessageA]
val TypeB = typeTag[MessageB]
def decode[T <: BaseMessage](xml: String)(implicit tag: TypeTag[T]): T = {
tag match {
case TypeA => MessageA()
case TypeB => MessageB()
}
}
Essentially I want to decode some xml string and return the corresponding message.
I got this to work though
def decode[T <: BaseMessage](xml: String)(implicit tag: TypeTag[T]): BaseMessage = {
tag match {
case TypeA => MessageA()
case TypeB => MessageB()
}
}
The above is returning BaseMessage
instead of T
and I'm having to cast at the call site. How do I get the decode function to return T? I'd like to be able to do the following
val a: MessageA = decode[MessageA]("xml...")
val b: MessageB = decode[MessageB]("xml...")
Upvotes: 1
Views: 497
Reputation: 18424
I think the typetag is probably a distraction and not needed. Perhaps you could create your own typeclass that does the actual work needed to create each of these instances. For instance:
trait Decoder[T <: BaseMessage] {
def decode(xml: String): T
}
implicit val messageADecoder = new Decoder[MessageA] {
def decode(xml: String): MessageA = MessageA()
}
// same for MessageB and other classes...
def decode[T <: BaseMessage](xml: String)(implicit dec: Decoder[T]): T = {
dec.decode(xml)
}
Upvotes: 1