Document CoreSyn and expand its API
authorMax Bolingbroke <batterseapower@hotmail.com>
Thu, 31 Jul 2008 05:29:41 +0000 (05:29 +0000)
committerMax Bolingbroke <batterseapower@hotmail.com>
Thu, 31 Jul 2008 05:29:41 +0000 (05:29 +0000)
compiler/coreSyn/CoreSyn.lhs

index ea22eb5..e259591 100644 (file)
@@ -3,46 +3,65 @@
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
 
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
 
-CoreSyn: A data type for the Haskell compiler midsection
-
 \begin{code}
 \begin{code}
+
+-- | CoreSyn holds all the main data types for use by for the Glasgow Haskell Compiler midsection
 module CoreSyn (
 module CoreSyn (
+       -- * Main data types
        Expr(..), Alt, Bind(..), AltCon(..), Arg, Note(..),
        CoreExpr, CoreAlt, CoreBind, CoreArg, CoreBndr,
        TaggedExpr, TaggedAlt, TaggedBind, TaggedArg, TaggedBndr(..),
 
        Expr(..), Alt, Bind(..), AltCon(..), Arg, Note(..),
        CoreExpr, CoreAlt, CoreBind, CoreArg, CoreBndr,
        TaggedExpr, TaggedAlt, TaggedBind, TaggedArg, TaggedBndr(..),
 
-       mkLets, mkLams, 
-       mkApps, mkTyApps, mkValApps, mkVarApps,
-       mkLit, mkIntLitInt, mkIntLit, 
-       mkConApp, mkCast,
+        -- ** 'Expr' construction
+       mkLets, mkLams,
+       mkApps, mkTyApps, mkVarApps,
+       
+       mkIntLit, mkIntLitInt,
+       mkWordLit, mkWordLitWord,
+       mkCharLit, mkStringLit,
+       mkFloatLit, mkFloatLitFloat,
+       mkDoubleLit, mkDoubleLitDouble,
+       
+       mkConApp, mkTyBind,
        varToCoreExpr, varsToCoreExprs,
 
        varToCoreExpr, varsToCoreExprs,
 
-       isTyVar, isId, cmpAltCon, cmpAlt, ltAlt,
+        isTyVar, isId, cmpAltCon, cmpAlt, ltAlt,
+       
+       -- ** Simple 'Expr' access functions and predicates
        bindersOf, bindersOfBinds, rhssOfBind, rhssOfAlts, 
        collectBinders, collectTyBinders, collectValBinders, collectTyAndValBinders,
        bindersOf, bindersOfBinds, rhssOfBind, rhssOfAlts, 
        collectBinders, collectTyBinders, collectValBinders, collectTyAndValBinders,
-       collectArgs, coreExprCc,
-       mkTyBind, flattenBinds, 
+       collectArgs, coreExprCc, flattenBinds, 
 
        isValArg, isTypeArg, valArgCount, valBndrCount, isRuntimeArg, isRuntimeVar,
 
 
        isValArg, isTypeArg, valArgCount, valBndrCount, isRuntimeArg, isRuntimeVar,
 
-       -- Unfoldings
+       -- * Unfolding data types
        Unfolding(..),  UnfoldingGuidance(..),  -- Both abstract everywhere but in CoreUnfold.lhs
        Unfolding(..),  UnfoldingGuidance(..),  -- Both abstract everywhere but in CoreUnfold.lhs
+       
+       -- ** Constructing 'Unfolding's
        noUnfolding, evaldUnfolding, mkOtherCon,
        noUnfolding, evaldUnfolding, mkOtherCon,
+       
+       -- ** Predicates and deconstruction on 'Unfolding'
        unfoldingTemplate, maybeUnfoldingTemplate, otherCons, 
        isValueUnfolding, isEvaldUnfolding, isCheapUnfolding, isCompulsoryUnfolding,
        hasUnfolding, hasSomeUnfolding, neverUnfold,
 
        unfoldingTemplate, maybeUnfoldingTemplate, otherCons, 
        isValueUnfolding, isEvaldUnfolding, isCheapUnfolding, isCompulsoryUnfolding,
        hasUnfolding, hasSomeUnfolding, neverUnfold,
 
-       -- Seq stuff
+       -- * Strictness
        seqExpr, seqExprs, seqUnfolding, 
 
        seqExpr, seqExprs, seqUnfolding, 
 
-       -- Annotated expressions
-       AnnExpr, AnnExpr'(..), AnnBind(..), AnnAlt, 
+       -- * Annotated expression data types
+       AnnExpr, AnnExpr'(..), AnnBind(..), AnnAlt,
+       
+       -- ** Operations on annotations
        deAnnotate, deAnnotate', deAnnAlt, collectAnnBndrs,
 
        deAnnotate, deAnnotate', deAnnAlt, collectAnnBndrs,
 
-       -- Core rules
+       -- * Core rule data types
        CoreRule(..),   -- CoreSubst, CoreTidy, CoreFVs, PprCore only
        CoreRule(..),   -- CoreSubst, CoreTidy, CoreFVs, PprCore only
-       RuleName, seqRules, ruleArity,
-       isBuiltinRule, ruleName, isLocalRule, ruleIdName, setRuleIdName
+       RuleName, 
+       
+       -- ** Operations on 'CoreRule's 
+       seqRules, ruleArity, ruleName, ruleIdName, ruleActivation_maybe,
+       setRuleIdName,
+       isBuiltinRule, isLocalRule
     ) where
 
 #include "HsVersions.h"
     ) where
 
 #include "HsVersions.h"
@@ -60,7 +79,9 @@ import FastString
 import Outputable
 import Util
 
 import Outputable
 import Util
 
-infixl 4 `mkApps`, `mkValApps`, `mkTyApps`, `mkVarApps`
+import Data.Word
+
+infixl 4 `mkApps`, `mkTyApps`, `mkVarApps`
 -- Left associative, so that we can say (f `mkTyApps` xs `mkVarApps` ys)
 \end{code}
 
 -- Left associative, so that we can say (f `mkTyApps` xs `mkVarApps` ys)
 \end{code}
 
@@ -75,79 +96,166 @@ These data types are the heart of the compiler
 \begin{code}
 infixl 8 `App` -- App brackets to the left
 
 \begin{code}
 infixl 8 `App` -- App brackets to the left
 
-data Expr b    -- "b" for the type of binders, 
-  = Var          Id
-  | Lit   Literal
-  | App   (Expr b) (Arg b)             -- See Note [CoreSyn let/app invariant]
-  | Lam   b (Expr b)
-  | Let   (Bind b) (Expr b)            -- See [CoreSyn let/app invariant],
-                                       -- and [CoreSyn letrec invariant]
-  | Case  (Expr b) b Type [Alt b]      -- Binder gets bound to value of scrutinee
-                                       -- See Note [CoreSyn case invariants]
-  | Cast  (Expr b) Coercion
-  | Note  Note (Expr b)
-  | Type  Type                 -- This should only show up at the top
-                               -- level of an Arg
-
-type Arg b = Expr b            -- Can be a Type
-
-type Alt b = (AltCon, [b], Expr b)     -- (DEFAULT, [], rhs) is the default alternative
-
-data AltCon = DataAlt DataCon  -- Invariant: the DataCon is always from 
-                               -- a *data* type, and never from a *newtype*
-           | LitAlt  Literal
-           | DEFAULT
+-- | This is the data type that represents GHCs core intermediate language. Currently
+-- GHC uses System FC <http://research.microsoft.com/~simonpj/papers/ext-f/> for this purpose,
+-- which is closely related to the simpler and better known System F <http://en.wikipedia.org/wiki/System_F>.
+--
+-- We get from Haskell source to this Core language in a number of stages:
+--
+-- 1. The source code is parsed into an abstract syntax tree, which is represented
+--    by the data type 'HsExpr.HsExpr' with the names being 'RdrName.RdrNames'
+--
+-- 2. This syntax tree is /renamed/, which attaches a 'Unique.Unique' to every 'RdrName.RdrName'
+--    (yielding a 'Name.Name') to disambiguate identifiers which are lexically identical. 
+--    For example, this program:
+--
+-- @
+--      f x = let f x = x + 1
+--            in f (x - 2)
+-- @
+--
+--    Would be renamed by having 'Unique's attached so it looked something like this:
+--
+-- @
+--      f_1 x_2 = let f_3 x_4 = x_4 + 1
+--                in f_3 (x_2 - 2)
+-- @
+--
+-- 3. The resulting syntax tree undergoes type checking (which also deals with instantiating
+--    type class arguments) to yield a 'HsExpr.HsExpr' type that has 'Id.Id' as it's names.
+--
+-- 4. Finally the syntax tree is /desugared/ from the expressive 'HsExpr.HsExpr' type into
+--    this 'Expr' type, which has far fewer constructors and hence is easier to perform
+--    optimization, analysis and code generation on.
+--
+-- The type parameter @b@ is for the type of binders in the expression tree.
+data Expr b
+  = Var          Id                            -- ^ Variables
+  | Lit   Literal                       -- ^ Primitive literals
+  | App   (Expr b) (Arg b)             -- ^ Applications: note that the argument may be a 'Type'.
+                                        --
+                                        -- See "CoreSyn#let_app_invariant" for another invariant
+  | Lam   b (Expr b)                    -- ^ Lambda abstraction
+  | Let   (Bind b) (Expr b)            -- ^ Recursive and non recursive @let@s. Operationally
+                                        -- this corresponds to allocating a thunk for the things
+                                        -- bound and then executing the sub-expression.
+                                        -- 
+                                        -- #top_level_invariant#
+                                        -- #letrec_invariant#
+                                        --
+                                        -- The right hand sides of all top-level and recursive @let@s
+                                        -- /must/ be of lifted type (see "Type#type_classification" for
+                                        -- the meaning of /lifted/ vs. /unlifted/).
+                                        --
+                                        -- #let_app_invariant#
+                                        -- The right hand side of of a non-recursive 'Let' _and_ the argument of an 'App',
+                                        -- /may/ be of unlifted type, but only if the expression 
+                                        -- is ok-for-speculation.  This means that the let can be floated around 
+                                        -- without difficulty. For example, this is OK:
+                                        --
+                                       -- > y::Int# = x +# 1#
+                                       --
+                                       -- But this is not, as it may affect termination if the expression is floated out:
+                                       --
+                                       -- > y::Int# = fac 4#
+                                       --
+                                       -- In this situation you should use @case@ rather than a @let@. The function
+                                       -- 'CoreUtils.needsCaseBinding' can help you determine which to generate, or
+                                       -- alternatively use 'MkCore.mkCoreLet' rather than this constructor directly,
+                                       -- which will generate a @case@ if necessary
+                                       --
+                                       -- #type_let#
+                                       -- We allow a /non-recursive/ let to bind a type variable, thus:
+                                       --
+                                       -- > Let (NonRec tv (Type ty)) body
+                                       --
+                                       -- This can be very convenient for postponing type substitutions until
+                                        -- the next run of the simplifier.
+                                        --
+                                        -- At the moment, the rest of the compiler only deals with type-let
+                                        -- in a Let expression, rather than at top level.  We may want to revist
+                                        -- this choice.
+  | Case  (Expr b) b Type [Alt b]      -- ^ Case split. Operationally this corresponds to evaluating
+                                        -- the scrutinee (expression examined) to weak head normal form
+                                        -- and then examining at most one level of resulting constructor (i.e. you
+                                        -- cannot do nested pattern matching directly with this).
+                                        --
+                                        -- The binder gets bound to the value of the scrutinee,
+                                        -- and the 'Type' must be that of all the case alternatives
+                                       --
+                                       -- #case_invariants#
+                                       -- This is one of the more complicated elements of the Core language, and comes
+                                       -- with a number of restrictions:
+                                       --
+                                       -- The 'DEFAULT' case alternative must be first in the list, if it occurs at all.
+                                       --
+                                       -- The remaining cases are in order of increasing 
+                                       --      tag     (for 'DataAlts') or
+                                       --      lit     (for 'LitAlts').
+                                       -- This makes finding the relevant constructor easy, and makes comparison easier too.
+                                       --
+                                       -- The list of alternatives must be exhaustive. An /exhaustive/ case 
+                                       -- does not necessarily mention all constructors:
+                                       --
+                                       -- @
+                                        --      data Foo = Red | Green | Blue
+                                        --
+                                        -- ... case x of 
+                                        --      Red   -> True
+                                        --      other -> f (case x of 
+                                        --                      Green -> ...
+                                        --                      Blue  -> ... ) ...
+                                        -- @
+                                        --
+                                        -- The inner case does not need a @Red@ alternative, because @x@ can't be @Red@ at
+                                        -- that program point.
+  | Cast  (Expr b) Coercion             -- ^ Cast an expression to a particular type. This is used to implement @newtype@s
+                                        -- (a @newtype@ constructor or destructor just becomes a 'Cast' in Core) and GADTs.
+  | Note  Note (Expr b)                 -- ^ Notes. These allow general information to be
+                                        -- added to expressions in the syntax tree
+  | Type  Type                         -- ^ A type: this should only show up at the top
+                                        -- level of an Arg
+
+-- | Type synonym for expressions that occur in function argument positions.
+-- Only 'Arg' should contain a 'Type' at top level, general 'Expr' should not
+type Arg b = Expr b
+
+-- | A case split alternative. Consists of the constructor leading to the alternative,
+-- the variables bound from the constructor, and the expression to be executed given that binding.
+-- The default alternative is @(DEFAULT, [], rhs)@
+type Alt b = (AltCon, [b], Expr b)
+
+-- | A case alternative constructor (i.e. pattern match)
+data AltCon = DataAlt DataCon  -- ^ A plain data constructor: @case e of { Foo x -> ... }@.
+                                -- Invariant: the 'DataCon' is always from a @data@ type, and never from a @newtype@
+           | LitAlt  Literal   -- ^ A literal: @case e of { 1 -> ... }@
+           | DEFAULT           -- ^ Trivial alternative: @case e of { _ -> ... }@
         deriving (Eq, Ord)
 
         deriving (Eq, Ord)
 
-
+-- | Binding, used for top level bindings in a module and local bindings in a @let@.
 data Bind b = NonRec b (Expr b)
 data Bind b = NonRec b (Expr b)
-             | Rec [(b, (Expr b))]
+           | Rec [(b, (Expr b))]
 \end{code}
 
 -------------------------- CoreSyn INVARIANTS ---------------------------
 
 Note [CoreSyn top-level invariant]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 \end{code}
 
 -------------------------- CoreSyn INVARIANTS ---------------------------
 
 Note [CoreSyn top-level invariant]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-* The RHSs of all top-level lets must be of LIFTED type.
+See #toplevel_invariant#
 
 Note [CoreSyn letrec invariant]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Note [CoreSyn letrec invariant]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-* The RHS of a letrec must be of LIFTED type.
+See #letrec_invariant#
 
 Note [CoreSyn let/app invariant]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Note [CoreSyn let/app invariant]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-* The RHS of a non-recursive let, *and* the argument of an App,
-  may be of UNLIFTED type, but only if the expression 
-  is ok-for-speculation.  This means that the let can be floated around 
-  without difficulty.  e.g.
-       y::Int# = x +# 1#       ok
-       y::Int# = fac 4#        not ok [use case instead]
-This is intially enforced by DsUtils.mkDsLet and mkDsApp
+See #let_app_invariant#
+
+This is intially enforced by DsUtils.mkCoreLet and mkCoreApp
 
 Note [CoreSyn case invariants]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Note [CoreSyn case invariants]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Invariant: The DEFAULT case must be *first*, if it occurs at all
-
-Invariant: The remaining cases are in order of increasing 
-               tag     (for DataAlts)
-               lit     (for LitAlts)
-           This makes finding the relevant constructor easy,
-           and makes comparison easier too
-
-Invariant: The list of alternatives is ALWAYS EXHAUSTIVE,
-          meaning that it covers all cases that can occur
-
-    An "exhaustive" case does not necessarily mention all constructors:
-       data Foo = Red | Green | Blue
-
-       ...case x of 
-               Red   -> True
-               other -> f (case x of 
-                               Green -> ...
-                               Blue  -> ... )
-    The inner case does not need a Red alternative, because x can't be Red at
-    that program point.
-
+See #case_invariants#
 
 Note [CoreSyn let goal]
 ~~~~~~~~~~~~~~~~~~~~~~~
 
 Note [CoreSyn let goal]
 ~~~~~~~~~~~~~~~~~~~~~~~
@@ -158,23 +266,18 @@ Note [CoreSyn let goal]
 
 Note [Type let]
 ~~~~~~~~~~~~~~~
 
 Note [Type let]
 ~~~~~~~~~~~~~~~
-We allow a *non-recursive* let to bind a type variable, thus
-       Let (NonRec tv (Type ty)) body
-This can be very convenient for postponing type substitutions until
-the next run of the simplifier.
-
-At the moment, the rest of the compiler only deals with type-let
-in a Let expression, rather than at top level.  We may want to revist
-this choice.
+See #type_let#
 
 \begin{code}
 
 \begin{code}
+
+-- | Allows attaching extra information to points in expressions rather than e.g. identifiers.
 data Note
 data Note
-  = SCC CostCentre
+  = SCC CostCentre      -- ^ A cost centre annotation for profiling
 
 
-  | InlineMe           -- Instructs simplifer to treat the enclosed expression
+  | InlineMe           -- ^ Instructs the core simplifer to treat the enclosed expression
                        -- as very small, and inline it at its call sites
 
                        -- as very small, and inline it at its call sites
 
-  | CoreNote String     -- A generic core annotation, propagated but not used by GHC
+  | CoreNote String     -- ^ A generic core annotation, propagated but not used by GHC
 
 -- NOTE: we also treat expressions wrapped in InlineMe as
 -- 'cheap' and 'dupable' (in the sense of exprIsCheap, exprIsDupable)
 
 -- NOTE: we also treat expressions wrapped in InlineMe as
 -- 'cheap' and 'dupable' (in the sense of exprIsCheap, exprIsDupable)
@@ -197,58 +300,62 @@ data Note
 The CoreRule type and its friends are dealt with mainly in CoreRules,
 but CoreFVs, Subst, PprCore, CoreTidy also inspect the representation.
 
 The CoreRule type and its friends are dealt with mainly in CoreRules,
 but CoreFVs, Subst, PprCore, CoreTidy also inspect the representation.
 
-A Rule is 
-
-  "local"  if the function it is a rule for is defined in the
-          same module as the rule itself.
-
-  "orphan" if nothing on the LHS is defined in the same module
-          as the rule itself
-
 \begin{code}
 \begin{code}
+-- | A 'CoreRule' is:
+--
+-- * \"Local\" if the function it is a rule for is defined in the
+--   same module as the rule itself.
+--
+-- * \"Orphan\" if nothing on the LHS is defined in the same module
+--   as the rule itself
 data CoreRule
   = Rule { 
 data CoreRule
   = Rule { 
-       ru_name :: RuleName,
-       ru_act  :: Activation,  -- When the rule is active
+       ru_name :: RuleName,            -- ^ Name of the rule, for communication with the user
+       ru_act  :: Activation,          -- ^ When the rule is active
        
        -- Rough-matching stuff
        -- see comments with InstEnv.Instance( is_cls, is_rough )
        
        -- Rough-matching stuff
        -- see comments with InstEnv.Instance( is_cls, is_rough )
-       ru_fn    :: Name,       -- Name of the Id at the head of this rule
-       ru_rough :: [Maybe Name],       -- Name at the head of each argument
+       ru_fn    :: Name,               -- ^ Name of the 'Id.Id' at the head of this rule
+       ru_rough :: [Maybe Name],       -- ^ Name at the head of each argument to the left hand side
        
        -- Proper-matching stuff
        -- see comments with InstEnv.Instance( is_tvs, is_tys )
        
        -- Proper-matching stuff
        -- see comments with InstEnv.Instance( is_tvs, is_tys )
-       ru_bndrs :: [CoreBndr], -- Forall'd variables
-       ru_args  :: [CoreExpr], -- LHS args
+       ru_bndrs :: [CoreBndr],         -- ^ Variables quantified over
+       ru_args  :: [CoreExpr],         -- ^ Left hand side arguments
        
        -- And the right-hand side
        
        -- And the right-hand side
-       ru_rhs   :: CoreExpr,
+       ru_rhs   :: CoreExpr,           -- ^ Right hand side of the rule
 
        -- Locality
 
        -- Locality
-       ru_local :: Bool        -- The fn at the head of the rule is
+       ru_local :: Bool        -- ^ @True@ iff the fn at the head of the rule is
                                -- defined in the same module as the rule
                                -- defined in the same module as the rule
-                               -- and is not an implicit Id (like a record sel
-                               -- class op, or data con)
+                               -- and is not an implicit 'Id' (like a record selector,
+                               -- class operation, or data constructor)
+
                -- NB: ru_local is *not* used to decide orphan-hood
                --      c.g. MkIface.coreRuleToIfaceRule
     }
 
                -- NB: ru_local is *not* used to decide orphan-hood
                --      c.g. MkIface.coreRuleToIfaceRule
     }
 
-  | BuiltinRule {              -- Built-in rules are used for constant folding
-       ru_name :: RuleName,    -- and suchlike.  It has no free variables.
-       ru_fn :: Name,          -- Name of the Id at 
-                               -- the head of this rule
-       ru_nargs :: Int,        -- Number of args that ru_try expects,
-                               -- including type args
-       ru_try  :: [CoreExpr] -> Maybe CoreExpr }
-               -- This function does the rewrite.  It given too many
-               -- arguments, it simply discards them; the returned CoreExpr
-               -- is just the rewrite of ru_fn applied to the first ru_nargs args
+  -- | Built-in rules are used for constant folding
+  -- and suchlike.  They have no free variables.
+  | BuiltinRule {               
+       ru_name :: RuleName,    -- ^ As above
+       ru_fn :: Name,          -- ^ As above
+       ru_nargs :: Int,        -- ^ Number of arguments that 'ru_try' expects,
+                               -- including type arguments
+       ru_try  :: [CoreExpr] -> Maybe CoreExpr
+               -- ^ This function does the rewrite.  It given too many
+               -- arguments, it simply discards them; the returned 'CoreExpr'
+               -- is just the rewrite of 'ru_fn' applied to the first 'ru_nargs' args
+    }
                -- See Note [Extra args in rule matching] in Rules.lhs
 
 isBuiltinRule :: CoreRule -> Bool
 isBuiltinRule (BuiltinRule {}) = True
 isBuiltinRule _                       = False
 
                -- See Note [Extra args in rule matching] in Rules.lhs
 
 isBuiltinRule :: CoreRule -> Bool
 isBuiltinRule (BuiltinRule {}) = True
 isBuiltinRule _                       = False
 
+-- | The number of arguments the 'ru_fn' must be applied 
+-- to before the rule can match on it
 ruleArity :: CoreRule -> Int
 ruleArity (BuiltinRule {ru_nargs = n}) = n
 ruleArity (Rule {ru_args = args})      = length args
 ruleArity :: CoreRule -> Int
 ruleArity (BuiltinRule {ru_nargs = n}) = n
 ruleArity (Rule {ru_args = args})      = length args
@@ -256,12 +363,18 @@ ruleArity (Rule {ru_args = args})      = length args
 ruleName :: CoreRule -> RuleName
 ruleName = ru_name
 
 ruleName :: CoreRule -> RuleName
 ruleName = ru_name
 
+ruleActivation_maybe :: CoreRule -> Maybe Activation
+ruleActivation_maybe (BuiltinRule { })       = Nothing
+ruleActivation_maybe (Rule { ru_act = act }) = Just act
+
+-- | The 'Name' of the 'Id.Id' at the head of the rule left hand side
 ruleIdName :: CoreRule -> Name
 ruleIdName = ru_fn
 
 isLocalRule :: CoreRule -> Bool
 isLocalRule = ru_local
 
 ruleIdName :: CoreRule -> Name
 ruleIdName = ru_fn
 
 isLocalRule :: CoreRule -> Bool
 isLocalRule = ru_local
 
+-- | Set the 'Name' of the 'Id.Id' at the head of the rule left hand side
 setRuleIdName :: Name -> CoreRule -> CoreRule
 setRuleIdName nm ru = ru { ru_fn = nm }
 \end{code}
 setRuleIdName :: Name -> CoreRule -> CoreRule
 setRuleIdName nm ru = ru { ru_fn = nm }
 \end{code}
@@ -273,35 +386,50 @@ setRuleIdName nm ru = ru { ru_fn = nm }
 %*                                                                     *
 %************************************************************************
 
 %*                                                                     *
 %************************************************************************
 
-The @Unfolding@ type is declared here to avoid numerous loops, but it
-should be abstract everywhere except in CoreUnfold.lhs
+The @Unfolding@ type is declared here to avoid numerous loops
 
 \begin{code}
 
 \begin{code}
+-- | Records the /unfolding/ of an identifier, which is approximately the form the
+-- identifier would have if we substituted its definition in for the identifier.
+-- This type should be treated as abstract everywhere except in "CoreUnfold"
 data Unfolding
 data Unfolding
-  = NoUnfolding
+  = NoUnfolding                 -- ^ We have no information about the unfolding
 
 
-  | OtherCon [AltCon]          -- It ain't one of these
-                               -- (OtherCon xs) also indicates that something has been evaluated
+  | OtherCon [AltCon]          -- ^ It ain't one of these constructors.
+                               -- @OtherCon xs@ also indicates that something has been evaluated
                                -- and hence there's no point in re-evaluating it.
                                -- and hence there's no point in re-evaluating it.
-                               -- OtherCon [] is used even for non-data-type values
+                               -- @OtherCon []@ is used even for non-data-type values
                                -- to indicated evaluated-ness.  Notably:
                                -- to indicated evaluated-ness.  Notably:
-                               --      data C = C !(Int -> Int)
-                               --      case x of { C f -> ... }
-                               -- Here, f gets an OtherCon [] unfolding.
+                               --
+                               -- > data C = C !(Int -> Int)
+                               -- > case x of { C f -> ... }
+                               --
+                               -- Here, @f@ gets an @OtherCon []@ unfolding.
 
 
-  | CompulsoryUnfolding CoreExpr       -- There is no "original" definition,
+  | CompulsoryUnfolding CoreExpr       -- ^ There is /no original definition/,
                                        -- so you'd better unfold.
 
                                        -- so you'd better unfold.
 
-  | CoreUnfolding                      -- An unfolding with redundant cached information
-               CoreExpr                -- Template; binder-info is correct
-               Bool                    -- True <=> top level binding
-               Bool                    -- exprIsHNF template (cached); it is ok to discard a `seq` on
-                                       --      this variable
-               Bool                    -- True <=> doesn't waste (much) work to expand inside an inlining
-                                       --      Basically it's exprIsCheap
-               UnfoldingGuidance       -- Tells about the *size* of the template.
-
-
+  | CoreUnfolding
+               CoreExpr
+               Bool
+               Bool
+               Bool
+               UnfoldingGuidance
+  -- ^ An unfolding with redundant cached information. Parameters:
+  --
+  --  1) Template used to perform unfolding; binder-info is correct
+  --
+  --  2) Is this a top level binding?
+  --
+  --  3) 'exprIsHNF' template (cached); it is ok to discard a 'seq' on
+  --     this variable
+  --
+  --  4) Does this waste only a little work if we expand it inside an inlining?
+  --     Basically this is a cached version of 'exprIsCheap'
+  --
+  --  5) Tells us about the /size/ of the unfolding template
+
+-- | When unfolding should take place
 data UnfoldingGuidance
   = UnfoldNever
   | UnfoldIfGoodArgs   Int     -- and "n" value args
 data UnfoldingGuidance
   = UnfoldNever
   | UnfoldIfGoodArgs   Int     -- and "n" value args
@@ -317,7 +445,11 @@ data UnfoldingGuidance
                                -- a context (case (thing args) of ...),
                                -- (where there are the right number of arguments.)
 
                                -- a context (case (thing args) of ...),
                                -- (where there are the right number of arguments.)
 
-noUnfolding, evaldUnfolding :: Unfolding
+noUnfolding :: Unfolding
+-- ^ There is no known 'Unfolding'
+evaldUnfolding :: Unfolding
+-- ^ This unfolding marks the associated thing as being evaluated
+
 noUnfolding    = NoUnfolding
 evaldUnfolding = OtherCon []
 
 noUnfolding    = NoUnfolding
 evaldUnfolding = OtherCon []
 
@@ -335,48 +467,61 @@ seqGuidance _                           = ()
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
+-- | Retrieves the template of an unfolding: panics if none is known
 unfoldingTemplate :: Unfolding -> CoreExpr
 unfoldingTemplate (CoreUnfolding expr _ _ _ _) = expr
 unfoldingTemplate (CompulsoryUnfolding expr)   = expr
 unfoldingTemplate _ = panic "getUnfoldingTemplate"
 
 unfoldingTemplate :: Unfolding -> CoreExpr
 unfoldingTemplate (CoreUnfolding expr _ _ _ _) = expr
 unfoldingTemplate (CompulsoryUnfolding expr)   = expr
 unfoldingTemplate _ = panic "getUnfoldingTemplate"
 
+-- | Retrieves the template of an unfolding if possible
 maybeUnfoldingTemplate :: Unfolding -> Maybe CoreExpr
 maybeUnfoldingTemplate (CoreUnfolding expr _ _ _ _) = Just expr
 maybeUnfoldingTemplate (CompulsoryUnfolding expr)   = Just expr
 maybeUnfoldingTemplate _                            = Nothing
 
 maybeUnfoldingTemplate :: Unfolding -> Maybe CoreExpr
 maybeUnfoldingTemplate (CoreUnfolding expr _ _ _ _) = Just expr
 maybeUnfoldingTemplate (CompulsoryUnfolding expr)   = Just expr
 maybeUnfoldingTemplate _                            = Nothing
 
+-- | The constructors that the unfolding could never be: 
+-- returns @[]@ if no information is available
 otherCons :: Unfolding -> [AltCon]
 otherCons (OtherCon cons) = cons
 otherCons _               = []
 
 otherCons :: Unfolding -> [AltCon]
 otherCons (OtherCon cons) = cons
 otherCons _               = []
 
+-- | Determines if it is certainly the case that the unfolding will
+-- yield a value (something in HNF): returns @False@ if unsure
 isValueUnfolding :: Unfolding -> Bool
 isValueUnfolding :: Unfolding -> Bool
-       -- Returns False for OtherCon
 isValueUnfolding (CoreUnfolding _ _ is_evald _ _) = is_evald
 isValueUnfolding _                                = False
 
 isValueUnfolding (CoreUnfolding _ _ is_evald _ _) = is_evald
 isValueUnfolding _                                = False
 
+-- | Determines if it possibly the case that the unfolding will
+-- yield a value. Unlike 'isValueUnfolding' it returns @True@
+-- for 'OtherCon'
 isEvaldUnfolding :: Unfolding -> Bool
 isEvaldUnfolding :: Unfolding -> Bool
-       -- Returns True for OtherCon
 isEvaldUnfolding (OtherCon _)                    = True
 isEvaldUnfolding (CoreUnfolding _ _ is_evald _ _) = is_evald
 isEvaldUnfolding _                                = False
 
 isEvaldUnfolding (OtherCon _)                    = True
 isEvaldUnfolding (CoreUnfolding _ _ is_evald _ _) = is_evald
 isEvaldUnfolding _                                = False
 
+-- | Is the thing we will unfold into certainly cheap?
 isCheapUnfolding :: Unfolding -> Bool
 isCheapUnfolding (CoreUnfolding _ _ _ is_cheap _) = is_cheap
 isCheapUnfolding _                                = False
 
 isCheapUnfolding :: Unfolding -> Bool
 isCheapUnfolding (CoreUnfolding _ _ _ is_cheap _) = is_cheap
 isCheapUnfolding _                                = False
 
+-- | Must this unfolding happen for the code to be executable?
 isCompulsoryUnfolding :: Unfolding -> Bool
 isCompulsoryUnfolding (CompulsoryUnfolding _) = True
 isCompulsoryUnfolding _                       = False
 
 isCompulsoryUnfolding :: Unfolding -> Bool
 isCompulsoryUnfolding (CompulsoryUnfolding _) = True
 isCompulsoryUnfolding _                       = False
 
+-- | Do we have an available or compulsory unfolding?
 hasUnfolding :: Unfolding -> Bool
 hasUnfolding (CoreUnfolding _ _ _ _ _) = True
 hasUnfolding (CompulsoryUnfolding _)   = True
 hasUnfolding _                         = False
 
 hasUnfolding :: Unfolding -> Bool
 hasUnfolding (CoreUnfolding _ _ _ _ _) = True
 hasUnfolding (CompulsoryUnfolding _)   = True
 hasUnfolding _                         = False
 
+-- | Only returns False if there is no unfolding information available at all
 hasSomeUnfolding :: Unfolding -> Bool
 hasSomeUnfolding NoUnfolding = False
 hasSomeUnfolding _           = True
 
 hasSomeUnfolding :: Unfolding -> Bool
 hasSomeUnfolding NoUnfolding = False
 hasSomeUnfolding _           = True
 
+-- | Similar to @not . hasUnfolding@, but also returns @True@
+-- if it has an unfolding that says it should never occur
 neverUnfold :: Unfolding -> Bool
 neverUnfold NoUnfolding                                = True
 neverUnfold (OtherCon _)                       = True
 neverUnfold :: Unfolding -> Bool
 neverUnfold NoUnfolding                                = True
 neverUnfold (OtherCon _)                       = True
@@ -412,7 +557,7 @@ ltAlt :: Alt b -> Alt b -> Bool
 ltAlt a1 a2 = (a1 `cmpAlt` a2) == LT
 
 cmpAltCon :: AltCon -> AltCon -> Ordering
 ltAlt a1 a2 = (a1 `cmpAlt` a2) == LT
 
 cmpAltCon :: AltCon -> AltCon -> Ordering
--- Compares AltCons within a single list of alternatives
+-- ^ Compares 'AltCon's within a single list of alternatives
 cmpAltCon DEFAULT      DEFAULT    = EQ
 cmpAltCon DEFAULT      _           = LT
 
 cmpAltCon DEFAULT      DEFAULT    = EQ
 cmpAltCon DEFAULT      _           = LT
 
@@ -426,26 +571,34 @@ cmpAltCon con1 con2 = WARN( True, text "Comparing incomparable AltCons" <+>
                      LT
 \end{code}
 
                      LT
 \end{code}
 
-
 %************************************************************************
 %*                                                                     *
 \subsection{Useful synonyms}
 %*                                                                     *
 %************************************************************************
 
 %************************************************************************
 %*                                                                     *
 \subsection{Useful synonyms}
 %*                                                                     *
 %************************************************************************
 
-The common case
-
 \begin{code}
 \begin{code}
+-- | The common case for the type of binders and variables when
+-- we are manipulating the Core language within GHC
 type CoreBndr = Var
 type CoreBndr = Var
+-- | Expressions where binders are 'CoreBndr's
 type CoreExpr = Expr CoreBndr
 type CoreExpr = Expr CoreBndr
+-- | Argument expressions where binders are 'CoreBndr's
 type CoreArg  = Arg  CoreBndr
 type CoreArg  = Arg  CoreBndr
+-- | Binding groups where binders are 'CoreBndr's
 type CoreBind = Bind CoreBndr
 type CoreBind = Bind CoreBndr
+-- | Case alternatives where binders are 'CoreBndr's
 type CoreAlt  = Alt  CoreBndr
 \end{code}
 
 type CoreAlt  = Alt  CoreBndr
 \end{code}
 
-Binders are ``tagged'' with a \tr{t}:
+%************************************************************************
+%*                                                                     *
+\subsection{Tagging}
+%*                                                                     *
+%************************************************************************
 
 \begin{code}
 
 \begin{code}
+-- | Binders are /tagged/ with a t
 data TaggedBndr t = TB CoreBndr t      -- TB for "tagged binder"
 
 type TaggedBind t = Bind (TaggedBndr t)
 data TaggedBndr t = TB CoreBndr t      -- TB for "tagged binder"
 
 type TaggedBind t = Bind (TaggedBndr t)
@@ -468,41 +621,96 @@ instance Outputable b => OutputableBndr (TaggedBndr b) where
 %************************************************************************
 
 \begin{code}
 %************************************************************************
 
 \begin{code}
+-- | Apply a list of argument expressions to a function expression in a nested fashion. Prefer to
+-- use 'CoreUtils.mkCoreApps' if possible
 mkApps    :: Expr b -> [Arg b]  -> Expr b
 mkApps    :: Expr b -> [Arg b]  -> Expr b
+-- | Apply a list of type argument expressions to a function expression in a nested fashion
 mkTyApps  :: Expr b -> [Type]   -> Expr b
 mkTyApps  :: Expr b -> [Type]   -> Expr b
-mkValApps :: Expr b -> [Expr b] -> Expr b
+-- | Apply a list of type or value variables to a function expression in a nested fashion
 mkVarApps :: Expr b -> [Var] -> Expr b
 mkVarApps :: Expr b -> [Var] -> Expr b
+-- | Apply a list of argument expressions to a data constructor in a nested fashion. Prefer to
+-- use 'MkCore.mkCoreConApps' if possible
+mkConApp      :: DataCon -> [Arg b] -> Expr b
 
 mkApps    f args = foldl App                      f args
 mkTyApps  f args = foldl (\ e a -> App e (Type a)) f args
 
 mkApps    f args = foldl App                      f args
 mkTyApps  f args = foldl (\ e a -> App e (Type a)) f args
-mkValApps f args = foldl (\ e a -> App e a)       f args
 mkVarApps f vars = foldl (\ e a -> App e (varToCoreExpr a)) f vars
 mkVarApps f vars = foldl (\ e a -> App e (varToCoreExpr a)) f vars
+mkConApp con args = mkApps (Var (dataConWorkId con)) args
+
 
 
-mkLit         :: Literal -> Expr b
+-- | Create a machine integer literal expression of type @Int#@ from an @Integer@.
+-- If you want an expression of type @Int@ use 'MkCore.mkIntExpr'
 mkIntLit      :: Integer -> Expr b
 mkIntLit      :: Integer -> Expr b
+-- | Create a machine integer literal expression of type @Int#@ from an @Int@.
+-- If you want an expression of type @Int@ use 'MkCore.mkIntExpr'
 mkIntLitInt   :: Int     -> Expr b
 mkIntLitInt   :: Int     -> Expr b
-mkConApp      :: DataCon -> [Arg b] -> Expr b
+
+mkIntLit    n = Lit (mkMachInt n)
+mkIntLitInt n = Lit (mkMachInt (toInteger n))
+
+-- | Create a machine word literal expression of type  @Word#@ from an @Integer@.
+-- If you want an expression of type @Word@ use 'MkCore.mkWordExpr'
+mkWordLit     :: Integer -> Expr b
+-- | Create a machine word literal expression of type  @Word#@ from a @Word@.
+-- If you want an expression of type @Word@ use 'MkCore.mkWordExpr'
+mkWordLitWord :: Word -> Expr b
+
+mkWordLit     w = Lit (mkMachWord w)
+mkWordLitWord w = Lit (mkMachWord (toInteger w))
+
+-- | Create a machine character literal expression of type @Char#@.
+-- If you want an expression of type @Char@ use 'MkCore.mkCharExpr'
+mkCharLit :: Char -> Expr b
+-- | Create a machine string literal expression of type @Addr#@.
+-- If you want an expression of type @String@ use 'MkCore.mkStringExpr'
+mkStringLit :: String -> Expr b
+
+mkCharLit   c = Lit (mkMachChar c)
+mkStringLit s = Lit (mkMachString s)
+
+-- | Create a machine single precision literal expression of type @Float#@ from a @Rational@.
+-- If you want an expression of type @Float@ use 'MkCore.mkFloatExpr'
+mkFloatLit :: Rational -> Expr b
+-- | Create a machine single precision literal expression of type @Float#@ from a @Float@.
+-- If you want an expression of type @Float@ use 'MkCore.mkFloatExpr'
+mkFloatLitFloat :: Float -> Expr b
+
+mkFloatLit      f = Lit (mkMachFloat f)
+mkFloatLitFloat f = Lit (mkMachFloat (toRational f))
+
+-- | Create a machine double precision literal expression of type @Double#@ from a @Rational@.
+-- If you want an expression of type @Double@ use 'MkCore.mkDoubleExpr'
+mkDoubleLit :: Rational -> Expr b
+-- | Create a machine double precision literal expression of type @Double#@ from a @Double@.
+-- If you want an expression of type @Double@ use 'MkCore.mkDoubleExpr'
+mkDoubleLitDouble :: Double -> Expr b
+
+mkDoubleLit       d = Lit (mkMachDouble d)
+mkDoubleLitDouble d = Lit (mkMachDouble (toRational d))
+
+-- | Bind all supplied binding groups over an expression in a nested let expression. Prefer to
+-- use 'CoreUtils.mkCoreLets' if possible
 mkLets       :: [Bind b] -> Expr b -> Expr b
 mkLets       :: [Bind b] -> Expr b -> Expr b
+-- | Bind all supplied binders over an expression in a nested lambda expression. Prefer to
+-- use 'CoreUtils.mkCoreLams' if possible
 mkLams       :: [b] -> Expr b -> Expr b
 
 mkLams       :: [b] -> Expr b -> Expr b
 
-mkLit lit        = Lit lit
-mkConApp con args = mkApps (Var (dataConWorkId con)) args
-
 mkLams binders body = foldr Lam body binders
 mkLets binds body   = foldr Let body binds
 
 mkLams binders body = foldr Lam body binders
 mkLets binds body   = foldr Let body binds
 
-mkIntLit    n = Lit (mkMachInt n)
-mkIntLitInt n = Lit (mkMachInt (toInteger n))
 
 
+-- | Create a binding group where a type variable is bound to a type. Per "CoreSyn#type_let",
+-- this can only be used to bind something in a non-recursive @let@ expression
+mkTyBind :: TyVar -> Type -> CoreBind
+mkTyBind tv ty      = NonRec tv (Type ty)
+
+-- | Convert a binder into either a 'Var' or 'Type' 'Expr' appropriately
 varToCoreExpr :: CoreBndr -> Expr b
 varToCoreExpr v | isId v    = Var v
                 | otherwise = Type (mkTyVarTy v)
 
 varsToCoreExprs :: [CoreBndr] -> [Expr b]
 varsToCoreExprs vs = map varToCoreExpr vs
 varToCoreExpr :: CoreBndr -> Expr b
 varToCoreExpr v | isId v    = Var v
                 | otherwise = Type (mkTyVarTy v)
 
 varsToCoreExprs :: [CoreBndr] -> [Expr b]
 varsToCoreExprs vs = map varToCoreExpr vs
-
-mkCast   :: Expr b -> Coercion -> Expr b
-mkCast e co = Cast e co
 \end{code}
 
 
 \end{code}
 
 
@@ -513,15 +721,12 @@ mkCast e co = Cast e co
 %************************************************************************
 
 \begin{code}
 %************************************************************************
 
 \begin{code}
-mkTyBind :: TyVar -> Type -> CoreBind
-mkTyBind tv ty      = NonRec tv (Type ty)
-       -- Note [Type let]
-       -- A non-recursive let can bind a type variable
-
+-- | Extract every variable by this group
 bindersOf  :: Bind b -> [b]
 bindersOf (NonRec binder _) = [binder]
 bindersOf (Rec pairs)       = [binder | (binder, _) <- pairs]
 
 bindersOf  :: Bind b -> [b]
 bindersOf (NonRec binder _) = [binder]
 bindersOf (Rec pairs)       = [binder | (binder, _) <- pairs]
 
+-- | 'bindersOf' applied to a list of binding groups
 bindersOfBinds :: [Bind b] -> [b]
 bindersOfBinds binds = foldr ((++) . bindersOf) [] binds
 
 bindersOfBinds :: [Bind b] -> [b]
 bindersOfBinds binds = foldr ((++) . bindersOf) [] binds
 
@@ -532,22 +737,25 @@ rhssOfBind (Rec pairs)    = [rhs | (_,rhs) <- pairs]
 rhssOfAlts :: [Alt b] -> [Expr b]
 rhssOfAlts alts = [e | (_,_,e) <- alts]
 
 rhssOfAlts :: [Alt b] -> [Expr b]
 rhssOfAlts alts = [e | (_,_,e) <- alts]
 
-flattenBinds :: [Bind b] -> [(b, Expr b)]      -- Get all the lhs/rhs pairs
+-- | Collapse all the bindings in the supplied groups into a single
+-- list of lhs/rhs pairs suitable for binding in a 'Rec' binding group
+flattenBinds :: [Bind b] -> [(b, Expr b)]
 flattenBinds (NonRec b r : binds) = (b,r) : flattenBinds binds
 flattenBinds (Rec prs1   : binds) = prs1 ++ flattenBinds binds
 flattenBinds []                          = []
 \end{code}
 
 flattenBinds (NonRec b r : binds) = (b,r) : flattenBinds binds
 flattenBinds (Rec prs1   : binds) = prs1 ++ flattenBinds binds
 flattenBinds []                          = []
 \end{code}
 
-We often want to strip off leading lambdas before getting down to
-business.  @collectBinders@ is your friend.
-
-We expect (by convention) type-, and value- lambdas in that
-order.
-
 \begin{code}
 \begin{code}
+-- | We often want to strip off leading lambdas before getting down to
+-- business. This function is your friend.
 collectBinders              :: Expr b -> ([b],         Expr b)
 collectBinders              :: Expr b -> ([b],         Expr b)
+-- | Collect as many type bindings as possible from the front of a nested lambda
 collectTyBinders                    :: CoreExpr -> ([TyVar],     CoreExpr)
 collectTyBinders                    :: CoreExpr -> ([TyVar],     CoreExpr)
+-- | Collect as many value bindings as possible from the front of a nested lambda
 collectValBinders                   :: CoreExpr -> ([Id],        CoreExpr)
 collectValBinders                   :: CoreExpr -> ([Id],        CoreExpr)
+-- | Collect type binders from the front of the lambda first, 
+-- then follow up by collecting as many value bindings as possible
+-- from the resulting stripped expression
 collectTyAndValBinders              :: CoreExpr -> ([TyVar], [Id], CoreExpr)
 
 collectBinders expr
 collectTyAndValBinders              :: CoreExpr -> ([TyVar], [Id], CoreExpr)
 
 collectBinders expr
@@ -575,11 +783,9 @@ collectValBinders expr
     go ids body                      = (reverse ids, body)
 \end{code}
 
     go ids body                      = (reverse ids, body)
 \end{code}
 
-
-@collectArgs@ takes an application expression, returning the function
-and the arguments to which it is applied.
-
 \begin{code}
 \begin{code}
+-- | Takes a nested application expression and returns the the function
+-- being applied and the arguments to which it is applied
 collectArgs :: Expr b -> (Expr b, [Arg b])
 collectArgs expr
   = go expr []
 collectArgs :: Expr b -> (Expr b, [Arg b])
 collectArgs expr
   = go expr []
@@ -588,10 +794,9 @@ collectArgs expr
     go e        as = (e, as)
 \end{code}
 
     go e        as = (e, as)
 \end{code}
 
-coreExprCc gets the cost centre enclosing an expression, if any.
-It looks inside lambdas because (scc "foo" \x.e) = \x.scc "foo" e
-
 \begin{code}
 \begin{code}
+-- | Gets the cost centre enclosing an expression, if any.
+-- It looks inside lambdas because @(scc \"foo\" \\x.e) = \\x. scc \"foo\" e@
 coreExprCc :: Expr b -> CostCentre
 coreExprCc (Note (SCC cc) _)   = cc
 coreExprCc (Note _ e)          = coreExprCc e
 coreExprCc :: Expr b -> CostCentre
 coreExprCc (Note (SCC cc) _)   = cc
 coreExprCc (Note _ e)          = coreExprCc e
@@ -599,8 +804,6 @@ coreExprCc (Lam _ e)           = coreExprCc e
 coreExprCc _                   = noCostCentre
 \end{code}
 
 coreExprCc _                   = noCostCentre
 \end{code}
 
-
-
 %************************************************************************
 %*                                                                     *
 \subsection{Predicates}
 %************************************************************************
 %*                                                                     *
 \subsection{Predicates}
@@ -613,23 +816,29 @@ i.e. if type applications are actual lambdas because types are kept around
 at runtime.  Similarly isRuntimeArg.  
 
 \begin{code}
 at runtime.  Similarly isRuntimeArg.  
 
 \begin{code}
+-- | Will this variable exist at runtime?
 isRuntimeVar :: Var -> Bool
 isRuntimeVar = isId 
 
 isRuntimeVar :: Var -> Bool
 isRuntimeVar = isId 
 
+-- | Will this argument expression exist at runtime?
 isRuntimeArg :: CoreExpr -> Bool
 isRuntimeArg = isValArg
 
 isRuntimeArg :: CoreExpr -> Bool
 isRuntimeArg = isValArg
 
+-- | Returns @False@ iff the expression is a 'Type' expression at its top level
 isValArg :: Expr b -> Bool
 isValArg (Type _) = False
 isValArg _        = True
 
 isValArg :: Expr b -> Bool
 isValArg (Type _) = False
 isValArg _        = True
 
+-- | Returns @True@ iff the expression is a 'Type' expression at its top level
 isTypeArg :: Expr b -> Bool
 isTypeArg (Type _) = True
 isTypeArg _        = False
 
 isTypeArg :: Expr b -> Bool
 isTypeArg (Type _) = True
 isTypeArg _        = False
 
+-- | The number of binders that bind values rather than types
 valBndrCount :: [CoreBndr] -> Int
 valBndrCount = count isId
 
 valBndrCount :: [CoreBndr] -> Int
 valBndrCount = count isId
 
+-- | The number of argument expressions that are values rather than types at their top level
 valArgCount :: [Arg b] -> Int
 valArgCount = count isValArg
 \end{code}
 valArgCount :: [Arg b] -> Int
 valArgCount = count isValArg
 \end{code}
@@ -687,17 +896,17 @@ seqRules (Rule { ru_bndrs = bndrs, ru_args = args, ru_rhs = rhs } : rules)
 seqRules (BuiltinRule {} : rules) = seqRules rules
 \end{code}
 
 seqRules (BuiltinRule {} : rules) = seqRules rules
 \end{code}
 
-
-
 %************************************************************************
 %*                                                                     *
 %************************************************************************
 %*                                                                     *
-\subsection{Annotated core; annotation at every node in the tree}
+\subsection{Annotated core}
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
+-- | Annotated core: allows annotation at every node in the tree
 type AnnExpr bndr annot = (annot, AnnExpr' bndr annot)
 
 type AnnExpr bndr annot = (annot, AnnExpr' bndr annot)
 
+-- | A clone of the 'Expr' type but allowing annotation at every tree node
 data AnnExpr' bndr annot
   = AnnVar     Id
   | AnnLit     Literal
 data AnnExpr' bndr annot
   = AnnVar     Id
   | AnnLit     Literal
@@ -709,8 +918,10 @@ data AnnExpr' bndr annot
   | AnnNote    Note (AnnExpr bndr annot)
   | AnnType    Type
 
   | AnnNote    Note (AnnExpr bndr annot)
   | AnnType    Type
 
+-- | A clone of the 'Alt' type but allowing annotation at every tree node
 type AnnAlt bndr annot = (AltCon, [bndr], AnnExpr bndr annot)
 
 type AnnAlt bndr annot = (AltCon, [bndr], AnnExpr bndr annot)
 
+-- | A clone of the 'Bind' type but allowing annotation at every tree node
 data AnnBind bndr annot
   = AnnNonRec bndr (AnnExpr bndr annot)
   | AnnRec    [(bndr, AnnExpr bndr annot)]
 data AnnBind bndr annot
   = AnnNonRec bndr (AnnExpr bndr annot)
   | AnnRec    [(bndr, AnnExpr bndr annot)]
@@ -743,6 +954,7 @@ deAnnAlt (con,args,rhs) = (con,args,deAnnotate rhs)
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
+-- | As 'collectBinders' but for 'AnnExpr' rather than 'Expr'
 collectAnnBndrs :: AnnExpr bndr annot -> ([bndr], AnnExpr bndr annot)
 collectAnnBndrs e
   = collect [] e
 collectAnnBndrs :: AnnExpr bndr annot -> ([bndr], AnnExpr bndr annot)
 collectAnnBndrs e
   = collect [] e