因此,有C a Bool
形式的類型類有許多優點。主要是因爲當正常的C a
只是隱含地AND與一切有關時,它們讓你在兩個約束之間做任何邏輯運算。將任意類約束`C a`轉換爲`C a Bool`
如果我們考慮~
一類約束,這可以像這樣
class Equal x y b | x y -> b
instance Equal x x True
instance False ~ b => Equal x y b
但是是什麼讓這種情況下,特別是,把x x
在實例的頭部相當於x ~ y =>
然後x y
完成在頭上。對於其他類型類別,情況並非如此。 所以,如果我們試圖做類似的事情一類C
我們得到類似
class C' x b | x -> b
instance C x => C' x True
instance False ~ Bool => C' x b
不幸的是,這並不因爲只有其中的一個實例的工作將永遠不會回升,因爲他們不類型x
歧視所以任何類型都匹配兩個頭。
我也讀過https://www.haskell.org/haskellwiki/GHC/AdvancedOverlap,它再次不適用於任何類C
,因爲它要求您重寫原始類的所有實例。理想情況下,我希望我的代碼與GHC.Exts.Constraint
和KindSignatures
一起使用,以便C
可以是參數化的。
所以,像這樣一類
class Match (c :: * -> Constraint) x b | c x -> b
我怎樣寫的實例,以便Match c x True
當且僅當c x
,Match c x False
否則?
的'C一Bool'形式比'C了'更強。你實質上是在問如何收集類型類的一組實例,這是不可能的。 – user2407038 2014-12-05 13:13:51
@ user2407038不是我懷疑你,而是我之前聽說過類型系統是'不可能的',結果是錯誤的。 – 2014-12-05 13:34:15
我不知道我是否可以提出令人信服的論點,但我會嘗試。假設你寫了'Match'。在模塊A中,我定義了'數據X = X',並且'類A b x | b - > x; a :: Proxy b - > x;實例一個True Int;實例一個虛假的Bool','test :: forall x b y。 (匹配等式x b,A b y)=> x - > y; test _ = a(Proxy :: Proxy b)'。我有模塊B(進口A),其中'test X'的類型必須是'Int'。在模塊C(導入A)中,我有'實例Eq X',所以'測試X :: Bool'。模塊D導入B和C.模塊D不能強制B和C重新編譯,所以'test X'必須一次反常地有兩種類型。 – user2407038 2014-12-05 19:18:35