既然我們有內射類型族,那麼在類型族中使用數據族還有什麼用例嗎?數據族vs內注類族
回顧過去有關數據族的StackOverflow問題,幾年前有this question討論類型族和數據族之間的區別,以及this answer關於數據族的用例。兩者都表示數據家族的注入是他們最大的優勢。
看着docs on data families,我看到理由不重寫使用injective type families的數據族的所有用途。
例如,說我有一個數據家人(我已經從合併的文檔一些例子來嘗試在所有數據家庭的功能擠)
data family G a b
data instance G Int Bool = G11 Int | G12 Bool deriving (Eq)
newtype instance G() a = G21 a
data instance G [a] b where
G31 :: c -> G [Int] b
G32 :: G [a] Bool
我還不如把它改寫爲
type family G a b = g | g -> a b
type instance G Int Bool = G_Int_Bool
type instance G() a = G_Unit_a a
type instance G [a] b = G_lal_b a b
data G_Int_Bool = G11 Int | G12 Bool deriving (Eq)
newtype G_Unit_a a = G21 a
data G_lal_b a b where
G31 :: c -> G_lal_b [Int] b
G32 :: G_lal_b [a] Bool
不言而喻,數據族的關聯實例對應於具有相同類型族的關聯實例。那麼剩下的唯一區別就是我們在類型名稱空間中的東西少了嗎?
作爲後續,在類型命名空間中擁有更少的東西是否有益處?所有我能想到的是,這將成爲調試地獄的人玩這個在ghci
- 構造函數的類型似乎都表明,構造函數都在一個GADT ...
我認爲[this](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#constraints-in-kinds)可以用數據族完成,而不是type家族,但它甚至不適用於數據族 - 您可以聲明這樣的數據族,但試圖聲明任何實例導致錯誤。 – user2407038
@ user2407038我不確定我是否理解 - 該示例顯然適用於類型系列(正如您提供的鏈接所述),我也可以將它與數據系列一起使用,但我沒有看到它的好處。 (數據族T :: a - > *;數據實例T 42 = MkNat;數據實例T「不要恐慌!」= MkSymbol') – Alec
這些是完全不同的類型;用戶指南中的示例是關於* type *構造函數(不是值構造函數)中的等式約束('IsTypeLit a〜True')。你不能對類型族有任何約束,你可以聲明'數據族T :: forall a。 (IsTypeLit a〜'True)=> a - > *'但從來沒有任何'T'的實例。 – user2407038