7.8 Type and exception definitions

7.8.1 Type definitions

Type definitions bind type constructors to data types: eithervariant types, record types, type abbreviations, or abstract datatypes. They also bind the value constructors and record fieldsassociated with the definition.

type-definition::=type [nonrec] typedef { and typedef }
typedef::=[type-params] typeconstr-name type-information
type-information::=[type-equation] [type-representation] { type-constraint }
type-equation::== typexpr
type-representation::== [|] constr-decl { | constr-decl }
= record-decl
= |
type-params::=type-param
( type-param { , type-param } )
type-param::=[variance] ' ident
variance::=+
-
record-decl::={ field-decl { ; field-decl } [;] }
constr-decl::=(constr-name ∣ [] ∣ (::)) [ of constr-args ]
constr-args::=typexpr { * typexpr }
field-decl::=[mutable] field-name : poly-typexpr
type-constraint::=constraint ' ident = typexpr

See also the following language extensions:private types,generalized algebraic datatypes,attributes,extension nodes,extensible variant types andinline records.

Type definitions are introduced by the type keyword, andconsist in one or several simple definitions, possibly mutuallyrecursive, separated by the and keyword. Each simple definitiondefines one type constructor.

A simple definition consists in a lowercase identifier, possiblypreceded by one or several type parameters, and followed by anoptional type equation, then an optional type representation, and thena constraint clause. The identifier is the name of the typeconstructor being defined.

In the right-hand side of type definitions, references to one of thetype constructor name being defined are considered as recursive,unless type is followed by nonrec. The nonrec keyword wasintroduced in OCaml 4.02.2.

The optional type parameters are either one type variable 'ident,for type constructors with one parameter, or a list of type variables('ident1,…,' identn), for type constructors with severalparameters. Each type parameter may be prefixed by a varianceconstraint + (resp. -) indicating that the parameter iscovariant (resp. contravariant). These type parameters can appear inthe type expressions of the right-hand side of the definition,optionally restricted by a variance constraint ; i.e. acovariant parameter may only appear on the right side of a functionalarrow (more precisely, follow the left branch of an even number ofarrows), and a contravariant parameter only the left side (left branch ofan odd number of arrows). If the type has a representation oran equation, and the parameter is free (i.e. not bound via atype constraint to a constructed type), its variance constraint ischecked but subtyping etc. will use the inferred variance of theparameter, which may be less restrictive; otherwise (i.e. for abstracttypes or non-free parameters), the variance must be given explicitly,and the parameter is invariant if no variance is given.

The optional type equation =typexpr makes the defined typeequivalent to the type expression typexpr:one can be substituted for the other during typing.If no type equation is given, a new type is generated: the defined typeis incompatible with any other type.

The optional type representation describes the data structurerepresenting the defined type, by giving the list of associatedconstructors (if it is a variant type) or associated fields (if it isa record type). If no type representation is given, nothing isassumed on the structure of the type besides what is stated in theoptional type equation.

The type representation = [|] constr-decl { |constr-decl }describes a variant type. The constructor declarationsconstr-decl1, …, constr-decln describe the constructorsassociated to this variant type. The constructordeclaration constr-nameof typexpr1 typexprndeclares the name constr-name as a non-constant constructor, whosearguments have types typexpr1typexprn.The constructor declaration constr-namedeclares the name constr-name as a constantconstructor. Constructor names must be capitalized.

The type representation ={field-decl { ;field-decl } [;] }describes a record type. The field declarations field-decl1, …, field-decln describe the fields associated to this record type.The field declaration field-name: poly-typexpr declaresfield-name as a field whose argument has type poly-typexpr.The field declaration mutablefield-name: poly-typexprbehaves similarly; in addition, it allows physical modification ofthis field.Immutable fields are covariant, mutable fields are non-variant.Both mutable and immutable fields may have explicitly polymorphictypes. The polymorphism of the contents is statically checked whenevera record value is created or modified. Extracted values may have theirtypes instantiated.

The two components of a type definition, the optional equation and theoptional representation, can be combined independently, givingrise to four typical situations:

  • Abstract type: no equation, no representation.
  • When appearing in a module signature, this definition specifiesnothing on the type constructor, besides its number of parameters:its representation is hidden and it is assumed incompatible with anyother type.
  • Type abbreviation: an equation, no representation.
  • This defines the type constructor as an abbreviation for the typeexpression on the right of the = sign.
  • New variant type or record type: no equation, a representation.
  • This generates a new type constructor and defines associatedconstructors or fields, through which values of that type can bedirectly built or inspected.
  • Re-exported variant type or record type: an equation,a representation.
  • In this case, the type constructor is defined as an abbreviation forthe type expression given in the equation, but in addition theconstructors or fields given in the representation remain attached tothe defined type constructor. The type expression in the equation partmust agree with the representation: it must be of the same kind(record or variant) and have exactly the same constructors or fields,in the same order, with the same arguments. The type variables appearing as type parameters can optionally beprefixed by + or - to indicate that the type constructor iscovariant or contravariant with respect to this parameter. Thisvariance information is used to decide subtyping relations whenchecking the validity of :> coercions (see section 7.7.7).

For instance, type +'a t declares t as an abstract type that iscovariant in its parameter; this means that if the type τ is asubtype of the type σ, then τ t is a subtype of σ t. Similarly, type -'a t declares that the abstract type t iscontravariant in its parameter: if τ is a subtype of σ, thenσ t is a subtype of τ t. If no + or - varianceannotation is given, the type constructor is assumed non-variant in thecorresponding parameter. For instance, the abstract type declarationtype 'a t means that τ t is neither a subtype nor asupertype of σ t if τ is subtype of σ.

The variance indicated by the + and - annotations on parametersis enforced only for abstract and private types, or when there aretype constraints.Otherwise, for abbreviations, variant and record types without typeconstraints, the variance properties of the type constructorare inferred from its definition, and the variance annotations areonly checked for conformance with the definition.

The construct constraint'ident= typexpr allows thespecification oftype parameters. Any actual type argument corresponding to the typeparameter ident has to be an instance of typexpr (more precisely,ident and typexpr are unified). Type variables of typexpr canappear in the type equation and the type declaration.

7.8.2 Exception definitions

exception-definition::=exception constr-decl
exception constr-name = constr

Exception definitions add new constructors to the built-in varianttype exn of exception values. The constructors are declared asfor a definition of a variant type.

The form exceptionconstr-declgenerates a new exception, distinct from all other exceptions in the system.The form exceptionconstr-name= constrgives an alternate name to an existing exception.