redkal
redkal

Reputation: 13

Scala error Expression of type subtype doesn't conform to expected type T

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

Answers (1)

Joe K
Joe K

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

Related Questions