TypeCast的實際用途是什麼?
它不用於檢索關於存在類型的類型信息(這會破壞類型系統,所以它是不可能的)。要理解TypeCast
,我們首先必須瞭解有關haskell類型系統的一些特定細節。請看下面的激勵例如:
data TTrue
data TFalse
class TypeEq a b c | a b -> c
instance TypeEq x x TTrue
instance TypeEq x y TFalse
這裏的目標是有一個布爾標誌 - 在類型級別 - 它告訴你如果兩個類型相同。您可以使用~
進行類型等同 - 但這隻會導致您在等效類型上失敗(即Int ~ Bool
未編譯,而TypeEq Int Bool r
將給出r ~ TFalse
作爲推斷類型)。但是,這不會編譯 - 功能依賴衝突。原因很簡單 - x x
只是x y
(即x ~ y
=>x y == x x
)的實例,因此根據fundeps的規則(請參閱文檔以獲取規則的完整詳細信息),這兩個實例的值必須相同(c
(或者這兩個值必須相互檢驗 - 它們不是)。
的TypeEq
類存在於HList
庫 - 讓我們來看看它是如何實現的:
class HBool b => TypeEq x y b | x y -> b
instance TypeEq x x HTrue
instance (HBool b, TypeCast HFalse b) => TypeEq x y b
-- instance TypeEq x y HFalse -- would violate functional dependency
當然這些實例並不衝突 - HTrue
是的b
一個實例。可是等等! TypeCast HFalse b
暗示b
必須是HFalse
?是的,它的確如此,但編譯器在嘗試解決fundep衝突時未檢查類實例約束。這是允許這個類存在的關鍵「特徵」。作爲一個簡短的說明 - 這兩個實例仍然重疊。但是由於-XUndecidableInstances -XOverlappingInstances
,編譯器會選擇第一個實例優先,由於第一個實例更「特定」(在這種情況下,這意味着它最多有2個唯一類型 - x
和HTrue
,而另一個實例至多有3個)。您可以在文檔中找到UndecidableInstances
使用的全套規則。
爲什麼TypeCast是這樣寫的?
如果你看看HList的源代碼,有多種實現TypeCast
。一種實現方式是:
instance TypeCast x x
人們會假設的直接實例將起作用。不!從該文件中包含上述定義的註釋:
A generic implementation of type cast. For this implementation to
work, we need to import it at a higher level in the module hierarchy
than all clients of the class. Otherwise, type simplification will
inline TypeCast x y, which implies compile-time unification of x and y.
也就是說,類型簡化器(其工作是清除類型同義詞,不斷類限制使用)會看到x ~ y
在TypeCast x x
因爲這是隻有匹配的實例,但只在某些情況下。由於在不同情況下行爲不同的代碼是「非常差」,因此HList的作者有第二個實現,即原始文章中的一個。讓我們一起來看看:(!該簡化器不會做)
class TypeCast a b | a -> b, b -> a
class TypeCast' t a b | t a -> b, t b -> a
class TypeCast'' t a b | t a -> b, t b -> a
instance TypeCast' () a b => TypeCast a b
instance TypeCast'' t a b => TypeCast' t a b
instance TypeCast''() a a
在這種情況下,TypeCast x y
可以從未被簡化不看類約束;沒有實例頭這可能暗示x ~ y
。
但是,我們仍然需要在某個時間段聲明x ~ y
- 所以我們用更多的類來做到這一點! 我們知道a ~ b
在TypeCast a b
的唯一方法是TypeCast() a b
意味着a ~ b
。如果TypeCast''() a b
意味着a ~ b
,則只有這種情況。
我不能給你整個故事unfortunatley;我不知道爲什麼
instance TypeCast'() a b => TypeCast a b
instance TypeCast'() a a
不足夠(它的作品 - 我不知道爲什麼它不會被使用)。我懷疑它與錯誤消息有關。我相信你可以追蹤奧列格並問他!
最近的HList使用'〜'而不是'TypeCast'。您可以從archive.org獲取該文件 – aavogt