Haskell имеет синтаксис с ограничениями для определения семейств типов:
(1) type family Length (xs :: [*]) where
(2) Length '[] = 0
(3) Length (x ': xs) = 1 + Length xs
В строках (2) и (3) в левой части знака равенства (=) мы имеем только простую сопоставление образцов. На правой стороне знака равенства мы просто набираем функцию функции уровня и в качестве синтаксического сахара существуют операторы типа ((+) в строке (3)).
Нет никаких охранников, нет выражений case, нет синтаксиса if-then-else, no let и where и нет приложения частичной функции. Это не проблема, так как выражение отсутствующего случая может быть заменено специализированной функцией уровня типа, этот шаблон соответствует в разных случаях, отсутствующий синтаксис if-then-else может быть заменен на If функция Data.Type.Bool пакет.
Посмотрев на некоторые примеры, мы видим, что синтаксис соответствия шаблонов на уровне типа имеет по крайней мере один дополнительная функция, недоступная в обычных функциях уровня Haskell:
(1) type family Contains (lst :: [a]) (elem :: a) where
(2) Contains (x ': xs) (x) = 'True
(3) Contains '[] (x) = 'False
(4) Contains (x ': xs) (y) = Contains xs (y)
В строке (2) мы дважды используем переменную x. Строка (2) оценивает значение "True", если глава списка первого параметра
равен второму параметру.
Если мы будем делать то же самое в функции уровня ценности, GHC отвечает с ошибкой Conflicting definitions for 'x'
.
В функциях уровня значения мы должны добавить контекст Eq a =>
для компиляции функции.
Совпадение типов типового уровня похоже похоже на унификацию в старые времена Prolog. Я безуспешно googled для некоторой документации о синтаксисе функций уровня уровня.
- Почему GHC не требует что-то вроде ограничения равенства типа a ~ b в определении семейства типов Contains?
- Доступно ли равенство типов?
- Имеет ли тип семейства синтаксис другие дополнительные функции, недоступные на уровне значений?
- Где это документировано?