Using Sub-Types And Return Types in Scala to Process a Generic Object Into a Specific One
- by pr1001
I think this is about covariance but I'm weak on the topic...
I have a generic Event class used for things like database persistance, let's say like this:
class Event(
  subject: Long,
  verb: String,
  directobject: Option[Long],
  indirectobject: Option[Long],
  timestamp: Long)
{
  def getSubject = subject
  def getVerb = verb
  def getDirectObject = directobject
  def getIndirectObject = indirectobject
  def getTimestamp = timestamp
}
However, I have lots of different event verbs and I want to use pattern matching and such with these different event types, so I  will create some corresponding case classes:
trait EventCC
case class Login(user: Long, timestamp: Long) extends EventCC
case class Follow(
  follower: Long,
  followee: Long,
  timestamp: Long
) extends EventCC
Now, the question is, how can I easily convert generic Events to the specific case classes.
This is my first stab at it:
def event2CC[T <: EventCC](event: Event): T = event.getVerb match {
  case "login" => Login(event.getSubject, event.getTimestamp)
  case "follow" => Follow(
    event.getSubject,
    event.getDirectObject.getOrElse(0),
    event.getTimestamp
  )
  // ...
}
Unfortunately, this is wrong.
<console>:11: error: type mismatch;
 found   : Login
 required: T
             case "login" => Login(event.getSubject, event.getTimestamp)
                             ^
<console>:12: error: type mismatch;
 found   : Follow
 required: T
             case "follow" => Follow(event.getSubject, 
event.getDirectObject.getOrElse(0), event.getTimestamp)
Could someone with greater type-fu than me explain if, 1) if what I want to do is possible (or reasonable, for that matter), and 2) if so, how to fix event2CC. Thanks!