Как я могу desugar мои ГАДЦ? - PullRequest
0 голосов
/ 28 июня 2018

Я читал Принуждения и роли для чайников , и автор безоговорочно упомянул, что ГАДЦ были просто синтаксическим сахаром.

GADT являются синтаксическим сахаром поверх (~), поэтому ожидайте, что GADT будут иметь номинальные параметры типа роли.

Теперь автор не стал вдаваться в подробности, потому что это не было целью поста в блоге. Однако я заинтригован. Как я могу обесценить мои ГАДЦ?

Например, вот простой гетерогенный список с использованием GADT.

{-# Language GADTs, DataKinds, TypeOperators #-}

data HList a where
  Empty :: HList '[]
  Cons  :: a -> HList b -> HList (a ': b)

На что будет похожа десагаратная версия?

1 Ответ

0 голосов
/ 28 июня 2018

Вы могли бы втянуть свой 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 участвует в ограничениях равенства, он играет номинальную роль.

...