我怎样才能对我的 GADT 脱糖?
How can I desugar my GADTs?
我正在阅读 Coercions and Roles for Dummies,作者随手提到 GADT 只是语法糖。
GADTs are syntactic sugar on top of (~)
so expect GADTs to have nominal role type parameters.
现在作者没有进一步讨论这个,因为这不是博客的重点post。但是我很好奇。我怎样才能让我的 GADT 脱糖?
例如,这里是一个使用 GADT 的简单异构列表。
{-# Language GADTs, DataKinds, TypeOperators #-}
data HList a where
Empty :: HList '[]
Cons :: a -> HList b -> HList (a ': b)
脱糖后的版本会是什么样子?
你可以将你的 GADT 脱糖到这个:
data HList t where
Empty :: t ~ '[] => HList t
Cons :: t ~ (a ': b) => a -> HList b -> HList t
这不再是 "real" GADT,因为每个构造函数 returns 都是通用类型 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
涉及到等式约束,所以它的作用是名义上的。
我正在阅读 Coercions and Roles for Dummies,作者随手提到 GADT 只是语法糖。
GADTs are syntactic sugar on top of
(~)
so expect GADTs to have nominal role type parameters.
现在作者没有进一步讨论这个,因为这不是博客的重点post。但是我很好奇。我怎样才能让我的 GADT 脱糖?
例如,这里是一个使用 GADT 的简单异构列表。
{-# Language GADTs, DataKinds, TypeOperators #-}
data HList a where
Empty :: HList '[]
Cons :: a -> HList b -> HList (a ': b)
脱糖后的版本会是什么样子?
你可以将你的 GADT 脱糖到这个:
data HList t where
Empty :: t ~ '[] => HList t
Cons :: t ~ (a ': b) => a -> HList b -> HList t
这不再是 "real" GADT,因为每个构造函数 returns 都是通用类型 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
涉及到等式约束,所以它的作用是名义上的。