This is a definition of the generalized algebraic data type (GADT). This language feature was introduced in the 4.0 release of OCaml and the syntax of the regular algebraic data types (ADT) was extended with this column variant to enable constructor-specific constraints.
The regular ADT syntax <Constr> [of <args>]
is used to introduce a constructor <Constr>
that has the specified arguments, e.g.,
type student = Student of string * int
The generalized syntax, <Constr> : [<args>] -> <constr>
uses :
instead of of
but adds an extra place for specifying the type constraint, e.g.,
type student = Student : string * int -> student
The constraint has to be an instance of the defined type. And it is useful when either the defined type or the constructor arguments (or both) are polymorphic, i.e., reference type variables. A better example is a type-safe abstract syntax tree of an expression language, e.g.,
type _ exp =
| Int : int -> int exp
| Str : string -> string exp
| Cat : string exp * string exp -> string exp
| Add : int exp * int exp -> int exp
Using this representation we can write a statically typed interpreter where we will not have to deal with cases Add (Str "foo", Int 42)
as it is impossible to construct such values because of the constraints on the Cat
constructor, which requires that both arguments have the string
type.
Another use case of GADT is to enable existential types that could be used to implement dynamic typing and ad-hoc polymorphism ala Haskell type classes. In an existential constructor, some type variables that occur in the constructor argument types are not present in the constraint type, e.g.,
type show = Show : {data : 'a; show : 'a -> string} -> show
let show (Show {show; data}) = show data
So that now we can have a heterogeneous containers,
let entries = [
Show {data=42; show=string_of_int};
Show {data="foo"; show=fun x -> x};
]
Which we can show,
# List.map show entries;;
- : string list = ["42"; "foo"]
t
is a GADT. The documentation is here: ocaml.org/releases/4.13/htmlman/gadts.html. In essencet
represents a Peano model of the integers (it seems to me). So maybez
isn't such a useless type after all. – GeorgeanngeorgeannaZ
in the typez
shadowed by the types
similarly named tag? – Carlinecarling