Overview ======== The view taken in this description of the module system is that a program consists of a number of modules. Each module provides (exports) some entities to be used by other modules. The entities exported by a module may either be defined in the module, or imported from another module. The task of the module system is to keep track of the relations between names and the entities they refer to. Examples of the kinds of questions one might expect the module system to answer are: which entity does a name refer to, what names are in scope, what entities are exported by a module. The module system is fairly independent of the rest of Haskell. In fact, it is possible to convert a program consisting of multiple modules into a program consisting of a single module by concatenating the modules and replacing each name in the program with a unique name identifying the entity to which it refers. There are a few technicalities about such a conversion related to the defaulting mechanism of Haskell, but this is not relevant to our discussion (REPORT REFERENCE). Entities -------- _Entities_ are introduced in a program by declarations. They are the "building blocks" for other objects in a program. Programmers use _names_ to refer to entities. For example, the declaration: > f x = x + 2 introduces one entity - a function named #f#. We only consider top level declarations as those are the ones which may be exported for use by other modules. Another slightly more complicated (but nevertheless common in practice) example: > data List a = EmptyList | List { hd :: a, tl :: List a } There are five entities introduced by this declaration: * a type constructor named #List# * two value constructors named #Nil# and #List# respectively * two field selectors - #hd# and #tl# We note that it is possible to have different entities with the same name (e.g. the two #List# entities above). There are six varieties of entities: * functions * type constructors * value constructors * field selectors * classes * class methods One could perhaps also consider class instances to be entities as they are also introduced by declarations, but since in Haskell 98 there is no way to name them (and hence refer to them directly in a program) we choose not to. The varieties of entities are not very essential as the Haskell module system is reasonably uniform in the sense that all entities (with one exception to be discussed later) are treated in the same way. Other examples of non-entities are expressions, types and patterns. There is a subtle distinction we make between types and type constructors - types are made out of type constructors, so even though #List# and #Int# are entities #List Int# is not. Furthermore we distinguish between #Int# as a nullary type constructor and #Int# as a type (i.e. the application of the type constructor to no arguments). Subordinate entities -------------------- As the reader might have noticed there are relations between some entities. If we look at the #List# example above, we note that the value constructors #List# and #EmptyList#, and the filed selectors #hd# and #tl# "belong" to the type constructor #List#. Such entities are called _subordinate_ entities. Another example of subordinate entities are the methods of a class (as they belong to the class). The Haskell module system provides special mechanism to control which of those subordinate entities are to be imported/exported from a module. TODO: Where to put this? A module defines a type: | data T = A | B | C To export the type T and just the A value constructor: | module A ( T(A) ) where To export the type T and all its constructors: | module A (T(..)) where To export just the type T: | module A (T) where or | module a (T()) where There is no way to export just a constructor without the type, while the situation is slightly different when dealing with classes. For details of the semantics see the functions bellow. Quick tour of Haskell module system =================================== The basic unit of a program is the _module_. Every module has a name used to identify the module. This name is used when a programmer needs to _import_ a module, i.e. specify that she will be using (some of) the entities defined in the module. To refer to entities programmers use names. Most of the time simple names (plain old identifiers) are sufficient, but sometimes if two entities happen to have the same name one may use a _qualified name_ to disambiguate which one is meant. Exports ------- To reduce the number of name clashes in programs, a programmer may restrict which entities (or rather names of entities) may be used by other modules (i.e. are _exported_ by the module) and which are just local "helper" entities. This is done with the module's export specification. If the programmer wishes to export just the locally defined names of a module no export specification needs to be provided, however if a finer control over the exports of a module is desired an explicit export specification has to be written. It consists of an enumeration of the entities to be export, plus a few ways to abbreviate whole groups of entities are available. For example: | module A where | f = True is a module (with a name #A#) which will just export the locally defined entity #f#. However: | module A(g) where | f = True | g = 'a' will only export the entity #g#, while #f# may not be named in other modules. So far in out description we have been somewhat informal, freely mixing the notions of _names_ and _entities_. It is however important to be careful and keep in mind that those are different. Just because an entity is not exported by a module does not mean it may not be used by other modules. However there will be no way for a programmer to directly name this entity. For example if a type constructor defined in a module is not exported, programmers won't be able to write type signatures involving this type constructor in other modules, however they might still be able to create values of types made out of the type constructor. Similarly, if a function uses another function in its definition, but the second function is not in exported, in other modules programmers may use the first function but not the second. Imports ------- In the large majority of modules, programmers make use of entities defined in other modules - either libraries or components of the project being designed. To achieve this, a programmer needs to first import the entities using an _import declaration_, which specifies a module and some entities to be imported from it. Entities are exported with just a simple name. When they are imported one may typically refer to them either using the simple name or by qualifying the name with the name of the module from which the entity was imported (to avoid an ambiguity if there are two entities with the same simple name, or for readability purposes). For example suppose module #A# exports an entity with a name #f#, then | import A | | p = f -- use the unqualified name | q = A.f -- use the qualified name Sometimes however, it is more convenient to qualify the entity names not using the module name, but rather some other name. To achieve this one may use the #as# clause of an import declaration. For example: | import A_Module_With_A_Long_Name as M | | p = f -- use the unqualified name | q = M.f -- use the qualified name | | -- r = A_Module_With_A_Long_Name.f error Another use of the #as# clause is to "combine" imports. For example if module #A# exports #f#, and module #B# exports #g#, then: | import A as M | import B as M | | p = f -- use unqualified name | q = g -- use unqualified name | r = M.f -- use qualified name | s = M.g -- use qualified name | -- t = A.f error | -- u = B.f error Finally in some situations it is more convenient not to have unqualified names at all, i.e. a programmer might want to ensure that she always refers to entities using the qualified names. This is achieved using the #qualified# clause in an import. If module #A# exports #f#: | import qualified A | | -- p = f error, the unqualified name is not available | q = A.f -- use the qualified names One may also combine those clauses. TODO...