--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+ <head>
+ <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
+ <title>The GHC Commentary - Checking Types</title>
+ </head>
+
+ <body BGCOLOR="FFFFFF">
+ <h1>The GHC Commentary - Checking Types</h1>
+ <p>
+ Probably the most important phase in the frontend is the type checker,
+ which is located at <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/typecheck/"><code>fptools/ghc/compiler/typecheck/</code>.</a>
+ GHC type checks programs in their original Haskell form before the
+ desugarer converts them into Core code. This complicates the type
+ checker as it has to handle the much more verbose Haskell AST, but it
+ improves error messages, as those message are based on the same
+ structure that the user sees.
+ </p>
+ <p>
+ GHC defines the abstract syntax of Haskell programs in <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/hsSyn/HsSyn.lhs"><code>HsSyn</code></a>
+ using a structure that abstracts over the concrete representation of
+ bound occurences of identifiers and patterns. The module <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/typecheck/TcHsSyn.lhs"><code>TcHsSyn</code></a>
+ defines a number of helper function required by the type checker. Note
+ that the type <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/typecheck/TcRnTypes.lhs"><code>TcRnTypes</code></a>.<code>TcId</code>
+ used to represent identifiers in some signatures during type checking
+ is, in fact, nothing but a synonym for a <a href="vars.html">plain
+ <code>Id</code>.</a>
+ </p>
+ <p>
+ It is also noteworthy, that the representations of types changes during
+ type checking from <code>HsType</code> to <code>TypeRep.Type</code>.
+ The latter is a <a href="types.html">hybrid type representation</a> that
+ is used to type Core, but still contains sufficient information to
+ recover source types. In particular, the type checker maintains and
+ compares types in their <code>Type</code> form.
+ </p>
+
+ <h2>The Overall Flow of Things</h2>
+
+ <h4>Entry Points Into the Type Checker</h4>
+ <p>
+ The interface of the type checker (and <a
+ href="renamer.html">renamer</a>) to the rest of the compiler is provided
+ by <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/typecheck/TcRnDriver.lhs"><code>TcRnDriver</code></a>.
+ Entire modules are processed by calling <code>tcRnModule</code> and GHCi
+ uses <code>tcRnStmt</code>, <code>tcRnExpr</code>, and
+ <code>tcRnType</code> to typecheck statements and expressions, and to
+ kind check types, respectively. Moreover, <code>tcRnExtCore</code> is
+ provided to typecheck external Core code. Moreover,
+ <code>tcTopSrcDecls</code> is used by Template Haskell - more
+ specifically by <code>TcSplice.tc_bracket</code>
+ - to type check the contents of declaration brackets.
+ </p>
+
+ <h4>Renaming and Type Checking a Module</h4>
+ <p>
+ The function <code>tcRnModule</code> controls the complete static
+ analysis of a Haskell module. It sets up the combined renamer and type
+ checker monad, resolves all import statements, initiates the actual
+ renaming and type checking process, and finally, wraps off by processing
+ the export list.
+ </p>
+ <p>
+ The actual type checking and renaming process is initiated via
+ <code>TcRnDriver.tcRnSrcDecls</code>, which uses a helper called
+ <code>tc_rn_src_decls</code> to implement the iterative renaming and
+ type checking process required by <a href="../exts/th.html">Template
+ Haskell</a>. However, before it invokes <code>tc_rn_src_decls</code>,
+ it takes care of hi-boot files; afterwards, it simplifies type
+ constraints and zonking (see below regarding the later).
+ </p>
+ <p>
+ The function <code>tc_rn_src_decls</code> partitions static analysis of
+ a whole module into multiple rounds, where the initial round is followed
+ by an additional one for each toplevel splice. It collects all
+ declarations up to the next splice into an <code>HsDecl.HsGroup</code>
+ to rename and type check that <em>declaration group</em> by calling
+ <code>TcRnDriver.tcRnGroup</code>. Afterwards, it executes the
+ splice (if there are any left) and proceeds to the next group, which
+ includes the declarations produced by the splice.
+ </p>
+ <p>
+ The function <code>tcRnGroup</code>, finally, gets down to invoke the
+ actual renaming and type checking via
+ <code>TcRnDriver.rnTopSrcDecls</code> and
+ <code>TcRnDriver.tcTopSrcDecls</code>, respectively. The renamer, apart
+ from renaming, computes the global type checking environment, of type
+ <code>TcRnTypes.TcGblEnv</code>, which is stored in the type checking
+ monad before type checking commences.
+ </p>
+
+ <h2>Type Checking a Declaration Group</h2>
+ <p>
+ The type checking of a declaration group, performed by
+ <code>tcTopSrcDecls</code> starts by processing of the type and class
+ declarations of the current module, using the function
+ <code>TcTyClsDecls.tcTyAndClassDecls</code>. This is followed by a
+ first round over instance declarations using
+ <code>TcInstDcls.tcInstDecls1</code>, which in particular generates all
+ additional bindings due to the deriving process. Then come foreign
+ import declarations (<code>TcForeign.tcForeignImports</code>) and
+ default declarations (<code>TcDefaults.tcDefaults</code>).
+ </p>
+ <p>
+ Now, finally, toplevel value declarations (including derived ones) are
+ type checked using <code>TcBinds.tcTopBinds</code>. Afterwards,
+ <code>TcInstDcls.tcInstDecls2</code> traverses instances for the second
+ time. Type checking concludes with processing foreign exports
+ (<code>TcForeign.tcForeignExports</code>) and rewrite rules
+ (<code>TcRules.tcRules</code>). Finally, the global environment is
+ extended with the new bindings.
+ </p>
+
+ <h2>Type checking Type and Class Declarations</h2>
+ <p>
+ Type and class declarations are type checked in a couple of phases that
+ contain recursive dependencies - aka <em>knots.</em> The first knot
+ encompasses almost the whole type checking of these declarations and
+ forms the main piece of <code>TcTyClsDecls.tcTyAndClassDecls</code>.
+ </p>
+ <p>
+ Inside this big knot, the first main operation is kind checking, which
+ again involves a knot. It is implemented by <code>kcTyClDecls</code>,
+ which performs kind checking of potentially recursively-dependent type
+ and class declarations using kind variables for initially unknown kinds.
+ During processing the individual declarations some of these variables
+ will be instantiated depending on the context; the rest gets by default
+ kind <code>*</code> (during <em>zonking</em> of the kind signatures).
+ Type synonyms are treated specially in this process, because they can
+ have an unboxed type, but they cannot be recursive. Hence, their kinds
+ are inferred in dependency order. Moreover, in contrast to class
+ declarations and other type declarations, synonyms are not entered into
+ the global environment as a global <code>TyThing</code>.
+ (<code>TypeRep.TyThing</code> is a sum type that combines the various
+ flavours of typish entities, such that they can be stuck into type
+ environments and similar.)
+ </p>
+
+ <h2>More Details</h2>
+
+ <h4>Types Variables and Zonking</h4>
+ <p>
+ During type checking type variables are represented by mutable variables
+ - cf. the <a href="vars.html#TyVar">variable story.</a> Consequently,
+ unification can instantiate type variables by updating those mutable
+ variables. This process of instantiation is (for reasons that elude me)
+ called <a
+ href="http://www.dictionary.com/cgi-bin/dict.pl?term=zonk&db=*">zonking</a>
+ in GHC's sources. The zonking routines for the various forms of Haskell
+ constructs are responsible for most of the code in the module <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/typecheck/TcHsSyn.lhs"><code>TcHsSyn</code>,</a>
+ whereas the routines that actually operate on mutable types are defined
+ in <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/typecheck/TcMType.lhs"><code>TcMType</code></a>;
+ this includes the zonking of type variables and type terms, routines to
+ create mutable structures and update them as well as routines that check
+ constraints, such as that type variables in function signatures have not
+ been instantiated during type checking. The actual type unification
+ routine is <code>uTys</code> in the module <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/typecheck/TcUnify.lhs"><code>TcUnify</code></a>.
+ </p>
+ <p>
+ All type variables that may be instantiated (those in signatures
+ may not), but haven't been instantiated during type checking, are zonked
+ to <code>()</code>, so that after type checking all mutable variables
+ have been eliminated.
+ </p>
+
+ <h4>Type Representation</h4>
+ <p>
+ The representation of types is fixed in the module <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/typecheck/TcRep.lhs"><code>TcRep</code></a>
+ and exported as the data type <code>Type</code>. As explained in <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/typecheck/TcType.lhs"><code>TcType</code></a>,
+ GHC supports rank-N types, but, in the type checker, maintains the
+ restriction that type variables cannot be instantiated to quantified
+ types (i.e., the type system is predicative). The type checker floats
+ universal quantifiers outside and maintains types in prenex form.
+ (However, quantifiers can, of course, not float out of negative
+ positions.) Overall, we have
+ </p>
+ <blockquote>
+ <pre>
+sigma -> forall tyvars. phi
+phi -> theta => rho
+rho -> sigma -> rho
+ | tau
+tau -> tyvar
+ | tycon tau_1 .. tau_n
+ | tau_1 tau_2
+ | tau_1 -> tau_2</pre>
+ </blockquote>
+ <p>
+ where <code>sigma</code> is in prenex form; i.e., there is never a
+ forall to the right of an arrow in a <code>phi</code> type. Moreover, a
+ type of the form <code>tau</code> never contains a quantifier (which
+ includes arguments to type constructors).
+ </p>
+ <p>
+ Of particular interest are the variants <code>SourceTy</code> and
+ <code>NoteTy</code> of <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/typecheck/TypeRep.lhs"><code>TypeRep</code></a>.<code>Type</code>.
+ The constructor <code>SourceTy :: SourceType -> Type</code> represents a
+ type constraint; that is, a predicate over types represented by a
+ dictionary. The type checker treats a <code>SourceTy</code> as opaque,
+ but during the translation to core it will be expanded into its concrete
+ representation (i.e., a dictionary type) by the function <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/types/Type.lhs"><code>Type</code></a>.<code>sourceTypeRep</code>.
+ Note that newtypes are not covered by <code>SourceType</code>s anymore,
+ even if some comments in GHC still suggest this. Instead, all newtype
+ applications are initially represented as a <code>NewTcApp</code>, until
+ they are eliminated by calls to <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/types/Type.lhs"><code>Type</code></a>.<code>newTypeRep</code>.
+ </p>
+ <p>
+ The <code>NoteTy</code> constructor is used to add non-essential
+ information to a type term. Such information has the type
+ <code>TypeRep.TyNote</code> and is either the set of free type variables
+ of the annotated expression or the unexpanded version of a type synonym.
+ Free variables sets are cached as notes to save the overhead of
+ repeatedly computing the same set for a given term. Unexpanded type
+ synonyms are useful for generating comprehensible error messages, but
+ have no influence on the process of type checking.
+ </p>
+
+ <h4>Type Checking Environment</h4>
+ <p>
+ During type checking, GHC maintains a <em>type environment</em> whose
+ type definitions are fixed in the module <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/typecheck/TcRnTypes.lhs"><code>TcRnTypes</code></a> with the operations defined in
+<a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/typecheck/TcEnv.lhs"><code>TcEnv</code></a>.
+ Among other things, the environment contains all imported and local
+ instances as well as a list of <em>global</em> entities (imported and
+ local types and classes together with imported identifiers) and
+ <em>local</em> entities (locally defined identifiers). This environment
+ is threaded through the type checking monad, whose support functions
+ including initialisation can be found in the module <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/typecheck/TcRnMonad.lhs"><code>TcRnMonad</code>.</a>
+
+ <h4>Expressions</h4>
+ <p>
+ Expressions are type checked by <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/typecheck/TcExpr.lhs"><code>TcExpr</code>.</a>
+ <p>
+ Usage occurences of identifiers are processed by the function
+ <code>tcId</code> whose main purpose is to <a href="#inst">instantiate
+ overloaded identifiers.</a> It essentially calls
+ <code>TcInst.instOverloadedFun</code> once for each universally
+ quantified set of type constraints. It should be noted that overloaded
+ identifiers are replaced by new names that are first defined in the LIE
+ (Local Instance Environment?) and later promoted into top-level
+ bindings.
+
+ <h4><a name="inst">Handling of Dictionaries and Method Instances</a></h4>
+ <p>
+ GHC implements overloading using so-called <em>dictionaries.</em> A
+ dictionary is a tuple of functions -- one function for each method in
+ the class of which the dictionary implements an instance. During type
+ checking, GHC replaces each type constraint of a function with one
+ additional argument. At runtime, the extended function gets passed a
+ matching class dictionary by way of these additional arguments.
+ Whenever the function needs to call a method of such a class, it simply
+ extracts it from the dictionary.
+ <p>
+ This sounds simple enough; however, the actual implementation is a bit
+ more tricky as it wants to keep track of all the instances at which
+ overloaded functions are used in a module. This information is useful
+ to optimise the code. The implementation is the module <a
+ href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/typecheck/Inst.lhs"><code>Inst.lhs</code>.</a>
+ <p>
+ The function <code>instOverloadedFun</code> is invoked for each
+ overloaded usage occurence of an identifier, where overloaded means that
+ the type of the idendifier contains a non-trivial type constraint. It
+ proceeds in two steps: (1) Allocation of a method instance
+ (<code>newMethodWithGivenTy</code>) and (2) instantiation of functional
+ dependencies. The former implies allocating a new unique identifier,
+ which replaces the original (overloaded) identifier at the currently
+ type-checked usage occurrence.
+ <p>
+ The new identifier (after being threaded through the LIE) eventually
+ will be bound by a top-level binding whose rhs contains a partial
+ application of the original overloaded identifier. This papp applies
+ the overloaded function to the dictionaries needed for the current
+ instance. In GHC lingo, this is called a <em>method.</em> Before
+ becoming a top-level binding, the method is first represented as a value
+ of type <code>Inst.Inst</code>, which makes it easy to fold multiple
+ instances of the same identifier at the same types into one global
+ definition. (And probably other things, too, which I haven't
+ investigated yet.)
+
+ <p>
+ <strong>Note:</strong> As of 13 January 2001 (wrt. to the code in the
+ CVS HEAD), the above mechanism interferes badly with RULES pragmas
+ defined over overloaded functions. During instantiation, a new name is
+ created for an overloaded function partially applied to the dictionaries
+ needed in a usage position of that function. As the rewrite rule,
+ however, mentions the original overloaded name, it won't fire anymore
+ -- unless later phases remove the intermediate definition again. The
+ latest CVS version of GHC has an option
+ <code>-fno-method-sharing</code>, which avoids sharing instantiation
+ stubs. This is usually/often/sometimes sufficient to make the rules
+ fire again.
+
+ <p><small>
+<!-- hhmts start -->
+Last modified: Thu May 12 22:52:46 EST 2005
+<!-- hhmts end -->
+ </small>
+ </body>
+</html>