score:0

I am taking the liberty to construct a general case, because I don't know CRUD and it doesn't play a role:

trait Data[T]
trait Meta[T <: Data[T]] { def name: String }
val all = collection.mutable.Map[String, Meta[_]]()

Now the compiler tells you exactly what is wrong with

def add(c: Meta[_]) { all += c.name -> c }

It says:

error: type arguments [_$1] do not conform to trait
       Meta's type parameter bounds [T <: Data[T]]

So while Scala lets you construct the Map without complaining (honestly I don't know why), you run into the bounds of Meta's type parameter T when you try to actually store the value in the map.

The solution is to use either of the following forms. (1) type parameter for the method:

def add[T <: Data[T]](c: Meta[T]) { all += c.name -> c }

(2) Existential type

def add(c: Meta[T] forSome { type T <: Data[T] }) { all += c.name -> c }

Don't ask me about (2), I keep forgetting what the existential types are all about... Maybe someone else can offer an insight here as to whether (1) or (2) is better. (the only answer to a related question suggests that (1) and (2) are pretty much the same, where (1) furthermore allows you to subsequently refer to type T. While that is not necessary here, it is still the more readable version, I'd say)


Related Query

More Query from same tag