如何为我的GADT脱糖?

时间:2018-06-28 19:08:05

标签: haskell syntactic-sugar gadt

我正在读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)

已终止交易的版本会是什么样子?

1 个答案:

答案 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涉及平等约束,因此它具有名义上的作用。