我想在運行時恢復Scala中的依賴類型。我基本上想要歸檔一個類型保存映射,其中每個鍵都有一個關聯的類型,但所有存儲的鍵值對的類型信息對Map的用戶不可見(與真棒Shapeless Map不同)。在運行時恢復依賴類型
class Key[V] {
type Value = V
def ->(value: V) = Pair(this, value)
}
trait Pair {
val key: Key[_]
val value: key.Value
}
trait Map {
val pairs: Seq[Pair]
def get[V](key: Key[V]): Option[V] =
pairs.find(pair => pair.key eq key).map(_.value).asInstanceOf[Option[V]]
// ^ ^
// the runtime prove that pair.key.Value equals V |
// |
// 'Convince' the compile that I know what I do
}
用法:
val text = new Key[String]
val count = new Key[Int]
val map: Map = new Map { val pairs = text -> "Hello World!" :: Nil }
map.get(text) // Some(Hello World!), Type: Option[String]
map.get(count) // None, Type: Option[Int]
是否可以寫一個get
方法,無需使用顯式與asInstanceOf
或隱式鑄造用火柴有未經檢查的分支?
我試圖寫一對unapply
對,但遇到同樣的問題。
請注意,我省略了Pair-companion對象的定義。這裏的一個運行示例在Gist。
由於只有具體的實例,我不認爲這裏的運行時擦除是一個問題。或者相反,我不明白通用類型信息在這種情況下可以提供哪些幫助。必須有一個運行時檢查,但編譯器可能會確信第二個是不必要的。 –
get方法是通用的,所以它不能爲不同的值賦予不同的代碼路徑。因此,調用代碼必須能夠看到「Key」/「Value」關係,或者它是運行時檢查。 – lmm