Haskell Wiki неплохо объясняет, как использовать экзистенциальные типы, но я не совсем понимаю теорию. /p >
Рассмотрим этот пример экзистенциального типа:
data S = forall a. Show a => S a -- (1)
чтобы определить оболочку типа для вещей, которые мы можем преобразовать в String
. Вики упоминает, что мы действительно хотим определить тип типа
data S = S (exists a. Show a => a) -- (2)
то есть. истинный "экзистенциальный" тип - я думаю, что это "говорящий" конструктор данных S
принимает любой тип, для которого <<24 > существует и обертывает его ". Фактически, вы могли бы написать GADT следующим образом:
data S where -- (3)
S :: Show a => a -> S
Я не пробовал компилировать это, но кажется, что он должен работать. Для меня GADT, очевидно, эквивалентен коду (2), который мы хотели бы написать.
Однако для меня совершенно не очевидно, почему (1) эквивалентно (2). Почему перемещение конструктора данных вовне превращает forall
в exists
?
Ближайшая вещь, о которой я могу думать, - это De Morgan Laws в логике, где взаимозаменяемость порядка отрицания и квантификатора превращает экзистенциальные кванторы в универсальные кванторы и наоборот:
¬(∀x. px) ⇔ ∃x. ¬(px)
но конструкторы данных кажутся совершенно другим зверем для оператора отрицания.
Какова теория, лежащая в основе способности определять типы экзистенции с использованием forall
вместо несуществующего exists
?