DataKinds
позволяет использовать конструкторы уровня терминов на уровне типов.
После
data T = A | B | C
можно писать типы, проиндексированные значением T
data U (t :: T) = ...
foo :: U A -> U B -> ...
Здесь, однако, A
и B
используются как типы, а не как значения.Следовательно, они должны быть "продвинуты", используя цитату:
data U (t :: T) = ...
foo :: U 'A -> U 'B -> ...
То же самое происходит со знакомым синтаксисом списка.'[]
- пустой список, повышенный на уровне типа.'[a,b,c]
- это то же самое, что и a ': b ': c ': '[]
, список, продвигаемый на уровне типа.
type :: kind
'[] :: [k] -- polykinded! works for any kind k
'[ 'A, 'B, 'C] :: [T] -- mind the spaces, we do not want the char '['
'A ': '[] :: [T]
'[ Int, Bool ] :: [*] -- a list of types
'[ Int ] :: [*] -- a list of types with only one element
[Int] :: * -- a type "list of Int"
Обратите внимание на два последних случая, когда в кавычках отсутствует однозначный синтаксис.