Parameterized Modules

Parameterized modules are to modules what functions are to base
values. Just like a function returns a new value from the values of
its parameters, a parameterized module builds a new module from the
modules given as parameters. Parameterized modules are also called
functors.

The addition of functors to the module language increases the
opportunities for code reuse in structures.

Syntax

The syntactic sugar for defining and naming a functor extends to
multiple-argument functors:

Syntax

moduleName(Name1:signature1) ...(Namen:signaturen)=

structure

The application of a functor to its arguments is written thus:

Syntax

moduleName=functor(structure1) ...(structuren)
Note that each parameter is written between parentheses. The result
of the application can be either a simple module or a partially
applied functor, depending on the number of parameters of the functor.

Warning

There is no equivalent to functors at the level of signature: it is
not possible to build a signature by application of a ``functorial
signature'' to other signatures.

A closed functor is a functor that does not reference any module
except its parameters. Such a closed functor makes its communications
with other modules entirely explicit. This provides maximal
reusability, since the modules it references are determined at
application time only. There is a strong parallel between a closed
function (without free variables) and a closed functor.

Functors and Code Reuse

The Objective CAML standard library provides three modules defining
functors. Two of them take as argument a module implementing a
totally ordered data type, that is, a module with the following signature:

Function compare takes two arguments of type t
and returns a negative integer if the first is less than the second,
zero if both are equal, and a positive integer if the first is greater
than the second. Here is an example of totally ordered type: pairs of
integers equipped with lexicographic ordering.

The functor Make from module Map returns a module
that implements association tables whose keys are values of the
ordered type passed as argument. This module provides operations
similar to the operations on association lists from module
List, but using a more efficient and more complex data
structure (balanced binary trees).

The type SetIntPair.t is the type of sets of integer pairs,
with all the usual set operations provided in SetIntPair,
including a set comparison function SetIntPair.compare.
To illustrate the code reuse made possible by functors, we now build
sets of sets of integer pairs.

The Make functor from module Hashtbl is similar to
that from the Map module, but implements (imperative) hash
tables instead of (purely functional) balanced trees. The argument to
Hashtbl.Make is slightly different: in addition to the type
of the keys for the hash table, it must provide an equality function
testing the equality of two keys (instead of a full-fledged comparison
function), plus a hash function, that is, a function associating
integers to keys.

Local Module Definitions

The Objective CAML core language allows a module to be defined locally to an
expression.

Syntax

letmoduleName = structure

inexpr

For instance, we can use the Set module locally to write a
sort function over integer lists, by inserting each list element into a
set and finally converting the set to the sorted list of its elements.