我认为你最好的选择是围绕斯卡拉的Map
写一个包装。
我很小的实现:
class MyMap[K[_],+V[_]] private(map: Map[Any,Any]) {
def apply[T](key: K[T]): V[T] = map(key).asInstanceOf[V[T]]
def updated[T1,T2,V1[X] >: V[X]](key: K[T1], value: V1[T2])(implicit ev: T1 =:= T2) = new MyMap[K,V1](map.updated(key,value))
}
object MyMap {
def apply[K[_],V[_]] = new MyMap[K,V](Map.empty)
}
我使用的是铸铁内部,但因为你请确保进入MyMap
的键值对始终具有相同类型的参数,应该是非常安全的。
scala> val (ai,as,bi,bs) = (new A[Int], new A[String], new B[Int], new B[String])
ai: A[Int] = [email protected]
as: A[String] = [email protected]
bi: B[Int] = [email protected]
bs: B[String] = [email protected]
scala> var m = MyMap[A,B]
m: MyMap[A,B] = [email protected]
scala> m = m.updated(as,bs)
m: MyMap[A,B] = [email protected]
scala> m = m.updated(ai,bi)
m: MyMap[A,B] = [email protected]
scala> m(as)
res0: B[String] = [email protected]
scala> m(ai)
res1: B[Int] = [email protected]
无需混合:
scala> m = m.updated(ai,bs)
<console>:23: error: Cannot prove that Int =:= String.
m = m.updated(ai,bs)
^