我認爲你最好的選擇是圍繞斯卡拉的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)
^