Reorganisation of the source tree
[ghc-hetmet.git] / docs / comm / the-beast / typecheck.html
diff --git a/docs/comm/the-beast/typecheck.html b/docs/comm/the-beast/typecheck.html
new file mode 100644 (file)
index 0000000..8d22784
--- /dev/null
@@ -0,0 +1,316 @@
+<!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>