I am lost in scala generics.
I need a method storeUnit which accepts Unit‘s subclasses’s instances (e.q. Visit) and returns StoredUnit‘s subclasses’s instances (e.q. StoredVisit) but I am getting compilation errors.
trait StatsUnit { val ip: String }
case class Visit(ip: String) extends StatsUnit
case class Click(ip: String) extends StatsUnit
trait StoredStatsUnit extends StatsUnit { val id: String }
case class StoredVisit(id: String, ip: String) extends StoredStatsUnit
case class StoredClick(id: String, ip: String) extends StoredStatsUnit
def storeUnit[A <: StatsUnit, B <: StoredStatsUnit](statsUnit: A): B = {
statsUnit match {
case x: Visit => StoredVisit("myid", x.ip)
case x: Click => StoredClick("myid", x.ip)
}
}
/tmp/1.scala:11: error: type mismatch;
found : this.StoredVisit
required: B
case x: Visit => StoredVisit("myid", x.ip)
^
/tmp/1.scala:12: error: type mismatch;
found : this.StoredClick
required: B
case x: Click => StoredClick("myid", x.ip)
A comment first:
Unit!Unithas specific meaning in Scala – it’s equivalent to Java’svoid– and shadowing that definition is only going to cause troubles!However, the problem here is that you specify that your method will return an instance of
Band then you try to return something of typeStoredVisit. You don’t needBat all in this example, so the following will work fine: