The Mercury module system is relatively simple and straightforward.
Each module must start with a ‘:- module ModuleName’ declaration, specifying the name of the module.
An ‘:- interface.’ declaration indicates the start of the module’s interface section: this section specifies the entities that are exported by this module. Mercury provides support for abstract data types, by allowing the definition of a type to be kept hidden, with the interface only exporting the type name. The interface section may contain definitions of types, type classes, data constructors, instantiation states, and modes, and declarations for abstract data types, abstract type class instances, functions, predicates, and (sub-)modules. The interface section may not contain definitions for functions or predicates (i.e. clauses), or definitions of (sub-)modules.
An ‘:- implementation.’ declaration indicates the start of the module’s implementation section. Any entities declared in this section are local to the module (and its sub-modules) and cannot be used by other modules. The implementation section must contain definitions for all abstract data types, abstract instance declarations, functions, predicates, and sub-modules exported by the module, as well as for all local types, type class instances, functions, predicates, and sub-modules. The implementation section can be omitted if it is empty.
The module may optionally end with a ‘:- end_module ModuleName’ declaration; the name specified in the ‘end_module’ must be the same as that in the corresponding ‘module’ declaration.
If a module wishes to make use of entities exported by other modules,
then it must explicitly import those modules using one or more
‘:- import_module Modules’ or ‘:- use_module Modules’
declarations, in order to make those declarations visible.
In both cases, Modules is a comma-separated list of
fully-qualified module names.
These declarations may occur either in the interface or the implementation
section. If the imported entities are used in the interface section,
then the corresponding
declaration must also be in the interface section. If the imported
entities are only used in the implementation section, the
use_module declaration should be in
the implementation section.
The names of predicates, functions, constructors, constructor fields,
types, modes, insts, type classes,
and (sub-)modules can be explicitly module qualified using the ‘.’
operator, e.g. ‘module.name’ or ‘module.submodule.name’.
This is useful both for readability and for resolving name conflicts.
Uses of entities imported using
must be explicitly fully module qualified.
Currently we also support ‘__’ as an alternative module qualifier,
so you can write
module__name instead of
Certain optimizations require information or source code for predicates defined in other modules to be as effective as possible. At the moment, inlining and higher-order specialization are the only optimizations that the Mercury compiler can perform across module boundaries.
One module must export a predicate ‘main/2’, which must be declared as either
:- pred main(io.state::di, io.state::uo) is det.
:- pred main(io.state::di, io.state::uo) is cc_multi.
(or any declaration equivalent to one of the two above).
Mercury has a standard library which includes over 100 modules, including modules for lists, stacks, queues, priority queues, sets, bags (multi-sets), maps (dictionaries), random number generation, input/output, and filename and directory handling. See the Mercury Library Reference Manual for a list of the available modules, and for the documentation of each module.