Я пытаюсь вырвать синглы Haskell.
В статье Зачарованное программирование с помощью синглтонов и в своем блоге singletons v0.9 Released! Ричард Эйзенберг определяет тип данных Nat, который определяет натуральные числа с аксиомами peano:
data Nat = Zero | Succ Nat
Используя расширение языка DataKinds, этот тип данных повышается до уровня типа. Составляющие данных Zero и Succ продвигаются к конструкторам типа Zero и Succ. С этим мы получаем для каждого натурального числа единственный и уникальный соответствующий тип на уровне типа. Например, для 3 мы получаем "Succ (" Succ ( "Succ" Zero)). Итак, теперь у нас есть натуральные числа как типы.
Затем он определяет на уровне значения функцию плюс и на уровне типа тип семейства Plus чтобы операция добавления была доступна. С помощью функции продвижения/квазиготератора библиотеки синглтонов мы можем автоматически создайте семейство "Плюс" из функции "плюс". Поэтому мы можем избежать написания семейства типов.
До сих пор так хорошо!
С синтаксисом GADT он также определяет тип данных SNat:
data SNat :: Nat -> * where
SZero :: SNat Zero
SSucc :: SNat n -> SNat (Succ n)
В основном он только переносит тип Nat в конструктор SNat. Почему это необходимо? Что мы получаем? Являются ли типы данных Nat и SNat не изоморфными? Почему SNat синглтон, и почему Nat не синглтон? В обоих случаях каждый тип населен одним единственным значением, соответствующим натуральным числом.