Теперь, когда у нас есть инъективные типы семейств, существует ли другой вариант использования семейств данных над семействами типов?
Глядя на прошлые вопросы StackOverflow о семействах данных, этот вопрос пару лет назад обсуждал разницу между семействами типов и семействами данных и этот ответ о случаях использования семейств данных. Оба говорят, что инъективность семейств данных является их наибольшей силой.
Глядя на docs на семейства данных, я вижу, что причина не переписывать все виды использования семейств данных с помощью семейства инъективных типов.
Например, скажем, у меня есть семейство данных (я объединил некоторые примеры из документов, чтобы попытаться сжать все функции семейств данных)
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...