This chapter introduces the module system of Objective Caml.
A primary motivation for modules is to package together related
definitions (such as the definitions of a data type and associated
operations over that type) and enforce a consistent naming scheme for
these definitions. This avoids running out of names or accidentally
confusing names. Such a package is called a structure and
is introduced by the struct...end construct, which contains an
arbitrary sequence of definitions. The structure is usually given a
name with the module binding. Here is for instance a structure
packaging together a type of priority queues and their operations:
#module PrioQueue =
struct
type priority = int
type 'a queue = Empty | Node of priority * 'a * 'a queue * 'a queue
let empty = Empty
let rec insert queue prio elt =
match queue with
Empty -> Node(prio, elt, Empty, Empty)
| Node(p, e, left, right) ->
if prio <= p
then Node(prio, elt, insert right p e, left)
else Node(p, e, insert right prio elt, left)
exception Queue_is_empty
let rec remove_top = function
Empty -> raise Queue_is_empty
| Node(prio, elt, left, Empty) -> left
| Node(prio, elt, Empty, right) -> right
| Node(prio, elt, (Node(lprio, lelt, _, _) as left),
(Node(rprio, relt, _, _) as right)) ->
if lprio <= rprio
then Node(lprio, lelt, remove_top left, right)
else Node(rprio, relt, left, remove_top right)
let extract = function
Empty -> raise Queue_is_empty
| Node(prio, elt, _, _) as queue -> (prio, elt, remove_top queue)
end;;
module PrioQueue :
sig
type priority = int
and 'a queue = Empty | Node of priority * 'a * 'a queue * 'a queue
val empty : 'a queue
val insert : 'a queue -> priority -> 'a -> 'a queue
exception Queue_is_empty
val remove_top : 'a queue -> 'a queue
val extract : 'a queue -> priority * 'a * 'a queue
end
Outside the structure, its components can be referred to using the
``dot notation'', that is, identifiers qualified by a structure name.
For instance, PrioQueue.insert in a value context is
the function insert defined inside the structure
PrioQueue. Similarly, PrioQueue.queue in a type context is the
type queue defined in PrioQueue.
#PrioQueue.insert PrioQueue.empty 1 "hello";;
- : string PrioQueue.queue =
PrioQueue.Node (1, "hello", PrioQueue.Empty, PrioQueue.Empty)