Module expressions are the module-level equivalent of value expressions: they evaluate to modules, thus providing implementations for the specifications expressed in module types.
module-expr:
module-path
| struct {definition [;;]} end
| functor ( module-name : module-type ) -> module-expr
| module-expr ( module-expr )
| ( module-expr )
| ( module-expr : module-type )
definition:
let [rec] let-binding {and let-binding}
| external value-name : typexpr = external-declaration
| type-definition
| exception-definition
| class class-definition {and class-definition} end
| module module-name {( module-name : module-type )} [: module-type] = module-expr
| module type modtype-name = module-type
| open module-path
The expression module-path evaluates to the module bound to the name module-path.
The expression ( module-expr ) evaluates to the same module as
module-expr.
The expression ( module-expr : module-type ) checks that the
type of module-expr is a subtype of module-type, that is, that all
components specified in module-type are implemented in
module-expr, and their implementation meets the requirements given
in module-type. In other terms, it checks that the implementation
module-expr meets the type specification module-type. The whole
expression evaluates to the same module as module-expr, except that
all components not specified in module-type are hidden and can no
longer be accessed.
Structures struct...end are collections of definitions for
value names, type names, exceptions, module names and module type
names. The definitions are evaluated in the order in which they appear
in the structure. The scope of the bindings performed by the
definitions extend to the end of the structure. As a consequence, a
definition may refer to names bound by earlier definitions in the same
structure.
For compatibility with toplevel phrases (chapter 8)
and with Caml Light, an optional ;; is allowed after each
definition in a structure. The ;; has no semantic meaning. Also for
compatibility, ;; expr is allowed as a component of a structure,
meaning let _ = expr, i.e. evaluate expr for its side-effects.
A value definition let [rec] let-binding {and let-binding}
bind value names in the same way as a let...in... expression
(see section 5.8). The value names appearing in the
left-hand sides of the bindings are bound to the corresponding values
in the right-hand sides.
A value definition external value-name : typexpr = external-declaration
implements value-name as the external function specified in
external-declaration (see chapter 15).
A definition of one or several type components is written
type typedef {and typedef} and consists of a sequence
of mutually recursive definitions of type names.
Exceptions are defined with the syntax exception constr-decl.
The class keyword introduces one or several mutually recursive
class definitions, as described in section 5.10.
The basic form for defining a module component is
module module-name = module-expr, which evaluates module-expr and binds
the result to the name module-name.
One can write
instead ofmodulemodule-name:module-type=module-expr
Another derived form ismodulemodule-name=(module-expr:module-type).
which is equivalent tomodulemodule-name(name1:module-type1)...(namen:module-typen)=module-expr
modulemodule-name=functor(name1:module-type1)->...->module-expr
A definition for a module type is written
module type modtype-name = module-type.
It binds the name modtype-name to the module type denoted by the
expression module-type.
The expression open module-path in a structure does not define any
components nor perform any bindings. It simply affects the parsing of
the following items of the structure, allowing components of the
module denoted by module-path to be referred to by their simple names
name instead of path accesses module-path . name. The scope of
the open stops at the end of the structure expression.
The expression functor ( module-name : module-type ) -> module-expr evaluates to a functor that takes as argument modules of
the type module-type1, binds module-name to these modules,
evaluates module-expr in the extended environment, and returns the
resulting modules as results. No restrictions are placed on the type of the
functor argument; in particular, a functor may take another functor as
argument (``higher-order'' functor).
The expression module-expr1 ( module-expr2 ) evaluates
module-expr1 to a functor and module-expr2 to a module, and
applies the former to the latter. The type of module-expr2 must
match the type expected for the arguments of the functor module-expr1.