The directory fptools/ghc/compiler/basicTypes/
contains modules that define some of the essential types definition for
the compiler - such as, identifiers, variables, modules, and unique
names. Some of those are discussed in the following. See elsewhere for more
detailed information on:
Id
s
An Id
(defined in Id.lhs
essentially records information about value and data constructor
identifiers -- to be precise, in the case of data constructors, two
Id
s are used to represent the worker and wrapper functions
for the data constructor, respectively. The information maintained in
the Id
abstraction includes among other items strictness,
occurrence, specialisation, and unfolding information.
Due to the way Id
s are used for data constructors,
all Id
s are represented as variables, which contain a
varInfo
field of abstract type IdInfo.IdInfo
.
This is where the information about Id
s is really stored.
The following is a (currently, partial) list of the various items in an
IdInfo
:
OccInfo
data type is defined in the module BasicTypes.lhs
.
Apart from the trivial NoOccInfo
, it distinguishes
between variables that do not occur at all (IAmDead
),
occur just once (OneOcc
), or a loop breakers
(IAmALoopBreaker
).
Sets of variables, or more generally names, which are needed throughout
the compiler, are provided by the modules VarSet.lhs
and NameSet.lhs
,
respectively. Moreover, frequently maps from variables (or names) to
other data is needed. For example, a substitution is represented by a
finite map from variable names to expressions. Jobs like this are
solved by means of variable and name environments implemented by the
modules VarEnv.lhs
and NameEnv.lhs
.
VarSet
The Module VarSet
provides the types VarSet
,
IdSet
, and TyVarSet
, which are synonyms in the
current implementation, as Var
, Id
, and
TyVar
are synonyms. The module provides all the operations
that one would expect including the creating of sets from individual
variables and lists of variables, union and intersection operations,
element checks, deletion, filter, fold, and map functions.
The implementation is based on UniqSet
s,
which in turn are simply UniqFM
s
(i.e., finite maps with uniques as keys) that map each unique to the
variable that it represents.
NameSet
The Module NameSet
provides the same functionality as
VarSet
only for Name
s.
As for the difference between Name
s and Var
s,
a Var
is built from a Name
plus additional
information (mostly importantly type information).
VarEnv
The module VarEnv
provides the types VarEnv
,
IdEnv
, and TyVarEnv
, which are again
synonyms. The provided base functionality is similar to
VarSet
with the main difference that a type VarEnv
T
associates a value of type T
with each variable in
the environment, thus effectively implementing a finite map from
variables to values of type T
.
The implementation of VarEnv
is also by UniqFM
,
which entails the slightly surprising implication that it is
not possible to retrieve the domain of a variable environment.
In other words, there is no function corresponding to
VarSet.varSetElems :: VarSet -> [Var]
in
VarEnv
. This is because the UniqFM
used to
implement VarEnv
stores only the unique corresponding to a
variable in the environment, but not the entire variable (and there is
no mapping from uniques to variables).
In addition to plain variable environments, the module also contains
special substitution environments - the type SubstEnv
-
that associates variables with a special purpose type
SubstResult
.
NameEnv
The type NameEnv.NameEnv
is like VarEnv
only
for Name
s.