昨天的一个问题(链接)中提到了HList
(来自HList
包)的定义,其中使用了数据家族。基本上:
data family HList (l :: [*])
data instance HList '[] = HNil
newtype instance HList (x ': xs) = HCons1 (x, HList xs)
pattern HCons x xs = HCons1 (x, xs)
与通常的(在我看来更加优雅和直观)GADT定义不同
data HList (l :: [*]) where
HNil :: HList '[]
HCons :: x -> HList xs -> HList (x ': xs)
这是因为数据家族版本让我们强制转换(我们只能强制转换 HList(x':xs)
情况,因为它是一个 newtype instance
,但那已经足够了)。而GADT仅推断出 l
的名义角色(从而阻止任何强制转换)。 (我回答中提到的问题具有此的具体示例。)关于
HList
的作用系统对GADT的缺陷在这个两年前的问题中讨论过。基本上,GHC会自动将任何“类似于GADT”的类型变量标记为名义。鉴于自那以后一些时间已经过去,并且有关使角色在类型/数据族周围更加灵活的讨论,是否有任何前进之路(即一些现有想法、一些开放的Trac票证、任何事情)可以检查GADT中更有趣的角色(如
HList
)?在这里,GADT或DataKinds
和角色之间的相互作用存在一些根本性限制吗?需要实现/创建什么才能使其工作?