Я просто наткнулся на следующий фрагмент кода в OCaml's documentation about GADTs:OCaml `type a. at` синтаксис
let rec eval : type a. a term -> a = function
| Int n -> n
| Add -> (fun x y -> x + y)
| App (f, x) -> (eval f) (eval x)
, который после того, как оценивается в utop, имеет следующую подпись:
val eval : 'a term -> 'a = <fun>
Я также заметил, что, когда заменяя type a. a term -> a
на 'a term -> 'a
или просто удаляя подпись, функция больше не компилируется.
...
| Add -> (fun x y -> x + y)
...
Error: This pattern matches values of type (int -> int -> int) term
but a pattern was expected which matches values of type int term
Type int -> int -> int is not compatible with type int
И что это за обозначения? Что отличает его от 'a t
?
Это характерно для GADT?
нет, он не является полиморфным. Это то, что «а». 'для (см. 7.12 в руководстве). Система типов не будет рассматривать 'let f (x: 'a):' a = x + 1' ошибка, так как' int' может объединяться. То, что делает 'type a', создает локально абстрактный тип. В GADT каждая ветвь может иметь другой тип, созданный как «a», как показывает пример «Antoine». В ситуациях, когда вы хотите использовать конкретный тип в полиморфной функции, это позволяет ссылаться на тип. – nlucaroni
@nlucaroni 'тип a. ... 'обеспечивает, чтобы' a' был полиморфным. Это комбинация 'a. ... '(который применяет полиморфизм) и' (type a) '(который объявляет локально абстрактный тип). –
Полезно знать, спасибо Лев. – nlucaroni