I want to know if it is possible to create a map with values of different constructed types. Like this:
class WowClass[A <: HeyClass]
val map = Map[String, WowClass[A <: HeyClass]]()
so that the values can be different children of the HeyClass
?
You can definitely store subtypes of a declared value type V
in a map, but if you read from the map, all you know is that you get values of type V
, i.e., the upper type bound of your hierarchy. You could then pattern match on the values if you need to know more.
trait V
case class A1() extends V
case class A2() extends V
var map = Map[String, V]()
map += ("A1" -> A1())
map += ("A2" -> A2())
map.values.head match {
case a1: A1 => println("A1")
case a2: A2 => println("A2")
}
If that is not precise enough for your, have a look at HLists. They are, in a sense, a type-safe implementation of n-tuples, i.e., a map of fixed size with natural number keys and values of arbitrary types.
Viewing a (read-only) Map[K, V]
as a function K -> V
could help to understand why it is not directly possible to have a map that takes values of different types, and that also statically knows the exact type of the values returned for each key. Given the above function signature, how should it be possible to statically know that key "foo"
returns a value of V1 <: V
, whereas key "bar"
returns a value of type V2 <: V
? This additional information somehow would need to be part of the function signature, which it actually is in the case of HLists.