我正在读Coercions and Roles for Dummies,作者断然提到GADT只是语法糖。
GADT是
(~)
之上的语法糖,因此希望GADT具有名义上的角色类型参数。
现在,作者不再赘述,因为这不是博客文章的重点。但是我很感兴趣。我该如何减少GADT的使用?
例如,这是一个使用GADT的简单异构列表。
{-# Language GADTs, DataKinds, TypeOperators #-}
data HList a where
Empty :: HList '[]
Cons :: a -> HList b -> HList (a ': b)
已终止交易的版本会是什么样子?
答案 0 :(得分:4)
您可以将您的GADT分解成糖:
data HList t where
Empty :: t ~ '[] => HList t
Cons :: t ~ (a ': b) => a -> HList b -> HList t
这不再是“真实的” GADT,因为每个构造函数都返回通用类型HList t
,就像在普通的旧代数数据类型中一样。
诀窍在于,类型变量t
在结果类型HList t
中看起来不受限制,但实际上受到类型相等性约束t ~ ...
的限制,以便获得与变量相同的语义。原始类型。
如果您要完全删除GADT语法,可以执行以下操作。您仍然需要打开一些扩展以使用~
约束。
{-# LANGUAGE DataKinds, TypeOperators, TypeFamilies, ExistentialQuantification #-}
data HList2 t
= t ~ '[] => Empty2
| forall a b . t ~ (a ': b) => Cons2 a (HList2 b)
您提到的论文可能指出,由于t
涉及平等约束,因此它具有名义上的作用。