# The GHC Commentary - Sugar Free: From Haskell To Core

Up until after type checking, GHC keeps the source program in an abstract representation of Haskell source without removing any of the syntactic sugar (such as, list comprehensions) that could easily be represented by more primitive Haskell. This complicates part of the front-end considerably as the abstract syntax of Haskell (as exported by the module `HsSyn`) is much more complex than a simplified representation close to, say, the Haskell Kernel would be. However, having a representation that is as close as possible to the surface syntax simplifies the generation of clear error messages. As GHC (quite in contrast to "conventional" compilers) prints code fragments as part of error messages, the choice of representation is especially important.

Nonetheless, as soon as the input has passed all static checks, it is transformed into GHC's principal intermediate language that goes by the name of Core and whose representation is exported by the module `CoreSyn`. All following compiler phases, except code generation operate on Core. Due to Andrew Tolmach's effort, there is also an external representation for Core.

The conversion of the compiled module from `HsSyn` into that of `CoreSyn` is performed by a phase called the desugarer, which is located in `fptools/ghc/compiler/deSugar/`. It's operation is detailed in the following.

## Auxilliary Functions

The modules `DsMonad` defines the desugarer monad (of type `DsM`) which maintains the environment needed for desugaring. In particular, it encapsulates a unique supply for generating new variables, a map to lookup standard names (such as functions from the prelude), a source location for error messages, and a pool to collect warning messages generated during desugaring. Initialisation of the environment happens in the function `Desugar` `.desugar`, which is also the main entry point into the desugarer.

The generation of Core code often involves the use of standard functions for which proper identifiers (i.e., values of type `Id` that actually refer to the definition in the right Prelude) need to be obtained. This is supported by the function `DsMonad.dsLookupGlobalValue :: Name -> DsM Id`.

## Pattern Matching

Nested pattern matching with guards and everything is translated into the simple, flat case expressions of Core by the following modules:

`Match`:
  This modules contains the main pattern-matching compiler in the form of a function called `match`. There is some documentation as to how `match` works contained in the module itself. Generally, the implemented algorithm is similar to the one described in Phil Wadler's Chapter ? of Simon Peyton Jones' The Implementation of Functional Programming Languages. `Match` exports a couple of functions with not really intuitive names. In particular, it exports `match`, `matchWrapper`, `matchExport`, and `matchSimply`. The function `match`, which is the main work horse, is only used by the other matching modules. The function `matchExport` - despite it's name - is merely used internally in `Match` and handles warning messages (see below for more details). The actual interface to the outside is `matchWrapper`, which converts the output of the type checker into the form needed by the pattern matching compiler (i.e., a list of `EquationInfo`). Similar in function to `matchWrapper` is `matchSimply`, which provides an interface for the case where a single expression is to be matched against a single pattern (as, for example, is the case in bindings in a `do` expression).
`MatchCon`:
  This module generates code for a set of alternative constructor patterns that belong to a single type by means of the routine `matchConFamily`. More precisely, the routine gets a set of equations where the left-most pattern of each equation is a constructor pattern with a head symbol from the same type as that of all the other equations. A Core case expression is generated that distinguihes between all these constructors. The routine is clever enough to generate a sparse case expression and to add a catch-all default case only when needed (i.e., if the case expression isn't exhaustive already). There is also an explanation at the start of the modules.
`MatchLit`:
  Generates code for a set of alternative literal patterns by means of the routine `matchLiterals`. The principle is similar to that of `matchConFamily`, but all left-most patterns are literals of the same type.
`DsUtils`:
  This module provides a set of auxilliary definitions as well as the data types `EquationInfo` and `MatchResult` that form the input and output, respectively, of the pattern matching compiler.
`Check`:
  This module does not really contribute the compiling pattern matching, but it inspects sets of equations to find whether there are any overlapping patterns or non-exhaustive pattern sets. This task is implemented by the function `check`, which returns a list of patterns that are part of a non-exhaustive case distinction as well as a set of equation labels that can be reached during execution of the code; thus, the remaining equations are shadowed due to overlapping patterns. The function `check` is invoked and its result converted into suitable warning messages by the function `Match.matchExport` (which is a wrapper for `Match.match`).

The central function `match`, given a set of equations, proceeds in a number of steps:

1. It starts by desugaring the left-most pattern of each equation using the function `tidy1` (indirectly via `tidyEqnInfo`). During this process, non-elementary pattern (e.g., those using explicit list syntax `[x, y, ..., z]`) are converted to a standard constructor pattern and also irrefutable pattern are removed.
2. Then, a process called unmixing clusters the equations into blocks (without re-ordering them), such that the left-most pattern of all equations in a block are either all variables, all literals, or all constructors.
3. Each block is, then, compiled by `matchUnmixedEqns`, which forwards the handling of literal pattern blocks to `MatchLit.matchLiterals`, of constructor pattern blocks to `MatchCon.matchConFamily`, and hands variable pattern blocks back to `match`.

Last modified: Mon Feb 11 22:35:25 EST 2002