7.4 Type expressions

typexpr::=' ident
_
( typexpr )
[[?]label-name:] typexpr -> typexpr
typexpr { * typexpr }+
typeconstr
typexpr typeconstr
( typexpr { , typexpr } ) typeconstr
typexpr as ' ident
polymorphic-variant-type
< [..] >
< method-type { ; method-type } [; ∣ ; ..] >
# class-path
typexpr # class-path
( typexpr { , typexpr } ) # class-path
poly-typexpr::=typexpr
{ ' ident }+ . typexpr
method-type::=method-name : poly-typexpr

See also the following language extensions:first-class modules,attributes andextension nodes.

The table below shows the relative precedences and associativity ofoperators and non-closed type constructions. The constructions withhigher precedences come first.

OperatorAssociativity
Type constructor application
#
*
->right
as

Type expressions denote types in definitions of data types as well asin type constraints over patterns and expressions.

Type variables

The type expression 'ident stands for the type variable namedident. The type expression _ stands for either an anonymous typevariable or anonymous type parameters. In data type definitions, typevariables are names for the data type parameters. In type constraints,they represent unspecified types that can be instantiated by any typeto satisfy the type constraint. In general the scope of a named typevariable is the whole top-level phrase where it appears, and it canonly be generalized when leaving this scope. Anonymous variables haveno such restriction. In the following cases, the scope of named typevariables is restricted to the type expression where they appear:1) for universal (explicitly polymorphic) type variables;2) for type variables that only appear in public method specifications(as those variables will be made universal, as described insection 7.9.1);3) for variables used as aliases, when the type they are aliased towould be invalid in the scope of the enclosing definition (i.e.when it contains free universal type variables, or locallydefined types.)

Parenthesized types

The type expression (typexpr) denotes the same type astypexpr.

Function types

The type expression typexpr1-> typexpr2 denotes the type offunctions mapping arguments of type typexpr1 to results of typetypexpr2.

label-name: typexpr1-> typexpr2 denotes the same function type, butthe argument is labeled label.

?label-name: typexpr1-> typexpr2 denotes the type of functionsmapping an optional labeled argument of type typexpr1 to results oftype typexpr2. That is, the physical type of the function will betypexpr1option-> typexpr2.

Tuple types

The type expression typexpr1 typexprndenotes the type of tuples whose elements belong to types typexpr1,… typexprn respectively.

Constructed types

Type constructors with no parameter, as in typeconstr, are typeexpressions.

The type expression typexpr typeconstr, where typeconstr is a typeconstructor with one parameter, denotes the application of the unary typeconstructor typeconstr to the type typexpr.

The type expression (typexpr1,…, typexprn) typeconstr, wheretypeconstr is a type constructor with n parameters, denotes theapplication of the n-ary type constructor typeconstr to the typestypexpr1 through typexprn.

In the type expression typeconstr , the anonymous type expression stands in for anonymous type parameters and is equivalent to (, …,) with as many repetitions of _ as the arity oftypeconstr.

Aliased and recursive types

The type expression typexpras' ident denotes the same type astypexpr, and also binds the type variable ident to type typexpr bothin typexpr and in other types. In general the scope of an alias isthe same as for a named type variable, and covers the whole enclosingdefinition. If the type variableident actually occurs in typexpr, a recursive type is created. Recursivetypes for which there exists a recursive path that does not containan object or polymorphic variant type constructor are rejected, exceptwhen the -rectypes mode is selected.

If 'ident denotes an explicit polymorphic variable, and typexprdenotes either an object or polymorphic variant type, the row variableof typexpr is captured by 'ident, and quantified upon.

Polymorphic variant types

polymorphic-variant-type::=[ tag-spec-first { | tag-spec } ]
[> [ tag-spec ] { | tag-spec } ]
[< [|] tag-spec-full { | tag-spec-full } [ > { [tag-name]($49815e5ab82eadea.md#tag-name) }<sup>+</sup> ] ] </td></tr><tr><td> </td></tr><tr><td><a class="syntax" id="tag-spec-first">tag-spec-first</a></td><td>::=</td><td>tag-name [ of typexpr ]
[ typexpr ] | tag-spec
tag-spec::=[tag-name]($49815e5ab82eadea.md#tag-name) [ of [typexpr](http://caml.inria.fr/pub/docs/manual-ocaml/#typexpr) ] </td></tr><tr><td> </td><td>∣</td><td> [typexpr](http://caml.inria.fr/pub/docs/manual-ocaml/#typexpr) </td></tr><tr><td> </td></tr><tr><td><a class="syntax" id="tag-spec-full">tag-spec-full</a></td><td>::=</td><td>tag-name [ of [&] typexpr { & typexpr } ]
typexpr

Polymorphic variant types describe the values a polymorphic variantmay take.

The first case is an exact variant type: all possible tags areknown, with their associated types, and they can all be present.Its structure is fully known.

The second case is an open variant type, describing a polymorphicvariant value: it gives the list of all tags the value could take,with their associated types. This type is still compatible with avariant type containing more tags. A special case is the unknowntype, which does not define any tag, and is compatible with anyvariant type.

The third case is a closed variant type. It gives information aboutall the possible tags and their associated types, and which tags areknown to potentially appear in values. The exact variant type (firstcase) isjust an abbreviation for a closed variant type where all possible tagsare also potentially present.

In all three cases, tags may be either specified directly in the`tag-name [oftypexpr] form, or indirectly through a typeexpression, which must expand to anexact variant type, whose tag specifications are inserted in itsplace.

Full specifications of variant tags are only used for non-exact closedtypes. They can be understood as a conjunctive type for the argument:it is intended to have all the types enumerated in thespecification.

Such conjunctive constraints may be unsatisfiable. In such a case thecorresponding tag may not be used in a value of this type. Thisdoes not mean that the whole type is not valid: one can still useother available tags.Conjunctive constraints are mainly intended as output from the typechecker. When they are used in source programs, unsolvable constraintsmay cause early failures.

Object types

An object type< [method-type { ;method-type }] >is a record of method types.

Each method may have an explicit polymorphic type: { 'ident }+. typexpr. Explicit polymorphic variables have a local scope, andan explicit polymorphic type can only be unified to anequivalent one, where only the order and names of polymorphicvariables may change.

The type < {method-type;} ..> is thetype of an object whose method names and types are described bymethod-type1, …, method-typen, and possibly some othermethods represented by the ellipsis. This ellipsis actually isa special kind of type variable (called row variable in theliterature) that stands for any number of extra method types.

#-types

The type #class-path is a special kind of abbreviation. Thisabbreviation unifies with the type of any object belonging to a subclassof class class-path.It is handled in a special way as it usually hides a type variable (anellipsis, representing the methods that may be added in a subclass).In particular, it vanishes when the ellipsis gets instantiated.Each type expression #class-path defines a new type variable, sotype #class-path-># class-path is usually not the same astype (#class-pathas' ident) ->' ident.

Use of #-types to abbreviate polymorphic variant types is deprecated.If t is an exact variant type then #t translates to [<t],and #t[>[tag]($49815e5ab82eadea.md#tag-name)<sub>1</sub> … tagk] translates to[<t>[tag]($49815e5ab82eadea.md#tag-name)<sub>1</sub> … tagk]

Variant and record types

There are no type expressions describing (defined) variant types norrecord types, since those are always named, i.e. defined before useand referred to by name. Type definitions are described insection 7.8.1.