Sophie

Sophie

distrib > Fedora > 14 > x86_64 > by-pkgid > 8d1ef08c9e0d44c69764afc615a03d0d > files > 1680

ghc-ghc-devel-6.12.3-5.fc14.i686.rpm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<!-- Generated by HsColour, http://www.cs.york.ac.uk/fp/darcs/hscolour/ -->
<title>coreSyn/CoreSyn.lhs</title>
<link type='text/css' rel='stylesheet' href='hscolour.css' />
</head>
<body>
%
% (c) The University of Glasgow 2006
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%

\begin{code}
<pre><a name="line-1"></a>
<a name="line-2"></a><span class='hs-comment'>-- | CoreSyn holds all the main data types for use by for the Glasgow Haskell Compiler midsection</span>
<a name="line-3"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>CoreSyn</span> <span class='hs-layout'>(</span>
<a name="line-4"></a>	<span class='hs-comment'>-- * Main data types</span>
<a name="line-5"></a>	<span class='hs-conid'>Expr</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>Alt</span><span class='hs-layout'>,</span> <span class='hs-conid'>Bind</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>AltCon</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>Arg</span><span class='hs-layout'>,</span> <span class='hs-conid'>Note</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
<a name="line-6"></a>	<span class='hs-conid'>CoreExpr</span><span class='hs-layout'>,</span> <span class='hs-conid'>CoreAlt</span><span class='hs-layout'>,</span> <span class='hs-conid'>CoreBind</span><span class='hs-layout'>,</span> <span class='hs-conid'>CoreArg</span><span class='hs-layout'>,</span> <span class='hs-conid'>CoreBndr</span><span class='hs-layout'>,</span>
<a name="line-7"></a>	<span class='hs-conid'>TaggedExpr</span><span class='hs-layout'>,</span> <span class='hs-conid'>TaggedAlt</span><span class='hs-layout'>,</span> <span class='hs-conid'>TaggedBind</span><span class='hs-layout'>,</span> <span class='hs-conid'>TaggedArg</span><span class='hs-layout'>,</span> <span class='hs-conid'>TaggedBndr</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
<a name="line-8"></a>
<a name="line-9"></a>        <span class='hs-comment'>-- ** 'Expr' construction</span>
<a name="line-10"></a>	<span class='hs-varid'>mkLets</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkLams</span><span class='hs-layout'>,</span>
<a name="line-11"></a>	<span class='hs-varid'>mkApps</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkTyApps</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkVarApps</span><span class='hs-layout'>,</span>
<a name="line-12"></a>	
<a name="line-13"></a>	<span class='hs-varid'>mkIntLit</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkIntLitInt</span><span class='hs-layout'>,</span>
<a name="line-14"></a>	<span class='hs-varid'>mkWordLit</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkWordLitWord</span><span class='hs-layout'>,</span>
<a name="line-15"></a>	<span class='hs-varid'>mkCharLit</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkStringLit</span><span class='hs-layout'>,</span>
<a name="line-16"></a>	<span class='hs-varid'>mkFloatLit</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkFloatLitFloat</span><span class='hs-layout'>,</span>
<a name="line-17"></a>	<span class='hs-varid'>mkDoubleLit</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkDoubleLitDouble</span><span class='hs-layout'>,</span>
<a name="line-18"></a>	
<a name="line-19"></a>	<span class='hs-varid'>mkConApp</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkTyBind</span><span class='hs-layout'>,</span>
<a name="line-20"></a>	<span class='hs-varid'>varToCoreExpr</span><span class='hs-layout'>,</span> <span class='hs-varid'>varsToCoreExprs</span><span class='hs-layout'>,</span>
<a name="line-21"></a>
<a name="line-22"></a>        <span class='hs-varid'>isTyVar</span><span class='hs-layout'>,</span> <span class='hs-varid'>isId</span><span class='hs-layout'>,</span> <span class='hs-varid'>cmpAltCon</span><span class='hs-layout'>,</span> <span class='hs-varid'>cmpAlt</span><span class='hs-layout'>,</span> <span class='hs-varid'>ltAlt</span><span class='hs-layout'>,</span>
<a name="line-23"></a>	
<a name="line-24"></a>	<span class='hs-comment'>-- ** Simple 'Expr' access functions and predicates</span>
<a name="line-25"></a>	<span class='hs-varid'>bindersOf</span><span class='hs-layout'>,</span> <span class='hs-varid'>bindersOfBinds</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhssOfBind</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhssOfAlts</span><span class='hs-layout'>,</span> 
<a name="line-26"></a>	<span class='hs-varid'>collectBinders</span><span class='hs-layout'>,</span> <span class='hs-varid'>collectTyBinders</span><span class='hs-layout'>,</span> <span class='hs-varid'>collectValBinders</span><span class='hs-layout'>,</span> <span class='hs-varid'>collectTyAndValBinders</span><span class='hs-layout'>,</span>
<a name="line-27"></a>	<span class='hs-varid'>collectArgs</span><span class='hs-layout'>,</span> <span class='hs-varid'>coreExprCc</span><span class='hs-layout'>,</span> <span class='hs-varid'>flattenBinds</span><span class='hs-layout'>,</span> 
<a name="line-28"></a>
<a name="line-29"></a>	<span class='hs-varid'>isValArg</span><span class='hs-layout'>,</span> <span class='hs-varid'>isTypeArg</span><span class='hs-layout'>,</span> <span class='hs-varid'>valArgCount</span><span class='hs-layout'>,</span> <span class='hs-varid'>valBndrCount</span><span class='hs-layout'>,</span> <span class='hs-varid'>isRuntimeArg</span><span class='hs-layout'>,</span> <span class='hs-varid'>isRuntimeVar</span><span class='hs-layout'>,</span>
<a name="line-30"></a>
<a name="line-31"></a>	<span class='hs-comment'>-- * Unfolding data types</span>
<a name="line-32"></a>	<span class='hs-conid'>Unfolding</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>	<span class='hs-conid'>UnfoldingGuidance</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> 	<span class='hs-comment'>-- Both abstract everywhere but in CoreUnfold.lhs</span>
<a name="line-33"></a>	
<a name="line-34"></a>	<span class='hs-comment'>-- ** Constructing 'Unfolding's</span>
<a name="line-35"></a>	<span class='hs-varid'>noUnfolding</span><span class='hs-layout'>,</span> <span class='hs-varid'>evaldUnfolding</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkOtherCon</span><span class='hs-layout'>,</span>
<a name="line-36"></a>	
<a name="line-37"></a>	<span class='hs-comment'>-- ** Predicates and deconstruction on 'Unfolding'</span>
<a name="line-38"></a>	<span class='hs-varid'>unfoldingTemplate</span><span class='hs-layout'>,</span> <span class='hs-varid'>maybeUnfoldingTemplate</span><span class='hs-layout'>,</span> <span class='hs-varid'>otherCons</span><span class='hs-layout'>,</span> 
<a name="line-39"></a>	<span class='hs-varid'>isValueUnfolding</span><span class='hs-layout'>,</span> <span class='hs-varid'>isEvaldUnfolding</span><span class='hs-layout'>,</span> <span class='hs-varid'>isCheapUnfolding</span><span class='hs-layout'>,</span>
<a name="line-40"></a>        <span class='hs-varid'>isExpandableUnfolding</span><span class='hs-layout'>,</span> <span class='hs-varid'>isCompulsoryUnfolding</span><span class='hs-layout'>,</span>
<a name="line-41"></a>	<span class='hs-varid'>hasUnfolding</span><span class='hs-layout'>,</span> <span class='hs-varid'>hasSomeUnfolding</span><span class='hs-layout'>,</span> <span class='hs-varid'>neverUnfold</span><span class='hs-layout'>,</span>
<a name="line-42"></a>
<a name="line-43"></a>	<span class='hs-comment'>-- * Strictness</span>
<a name="line-44"></a>	<span class='hs-varid'>seqExpr</span><span class='hs-layout'>,</span> <span class='hs-varid'>seqExprs</span><span class='hs-layout'>,</span> <span class='hs-varid'>seqUnfolding</span><span class='hs-layout'>,</span> 
<a name="line-45"></a>
<a name="line-46"></a>	<span class='hs-comment'>-- * Annotated expression data types</span>
<a name="line-47"></a>	<span class='hs-conid'>AnnExpr</span><span class='hs-layout'>,</span> <span class='hs-conid'>AnnExpr'</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>AnnBind</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>AnnAlt</span><span class='hs-layout'>,</span>
<a name="line-48"></a>	
<a name="line-49"></a>	<span class='hs-comment'>-- ** Operations on annotations</span>
<a name="line-50"></a>	<span class='hs-varid'>deAnnotate</span><span class='hs-layout'>,</span> <span class='hs-varid'>deAnnotate'</span><span class='hs-layout'>,</span> <span class='hs-varid'>deAnnAlt</span><span class='hs-layout'>,</span> <span class='hs-varid'>collectAnnBndrs</span><span class='hs-layout'>,</span>
<a name="line-51"></a>
<a name="line-52"></a>	<span class='hs-comment'>-- * Core rule data types</span>
<a name="line-53"></a>	<span class='hs-conid'>CoreRule</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>	<span class='hs-comment'>-- CoreSubst, CoreTidy, CoreFVs, PprCore only</span>
<a name="line-54"></a>	<span class='hs-conid'>RuleName</span><span class='hs-layout'>,</span> 
<a name="line-55"></a>	
<a name="line-56"></a>	<span class='hs-comment'>-- ** Operations on 'CoreRule's </span>
<a name="line-57"></a>	<span class='hs-varid'>seqRules</span><span class='hs-layout'>,</span> <span class='hs-varid'>ruleArity</span><span class='hs-layout'>,</span> <span class='hs-varid'>ruleName</span><span class='hs-layout'>,</span> <span class='hs-varid'>ruleIdName</span><span class='hs-layout'>,</span> <span class='hs-varid'>ruleActivation_maybe</span><span class='hs-layout'>,</span>
<a name="line-58"></a>	<span class='hs-varid'>setRuleIdName</span><span class='hs-layout'>,</span>
<a name="line-59"></a>	<span class='hs-varid'>isBuiltinRule</span><span class='hs-layout'>,</span> <span class='hs-varid'>isLocalRule</span>
<a name="line-60"></a>    <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
<a name="line-61"></a>
<a name="line-62"></a><span class='hs-cpp'>#include "HsVersions.h"</span>
<a name="line-63"></a>
<a name="line-64"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CostCentre</span>
<a name="line-65"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Var</span>
<a name="line-66"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Type</span>
<a name="line-67"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Coercion</span>
<a name="line-68"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Name</span>
<a name="line-69"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Literal</span>
<a name="line-70"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>DataCon</span>
<a name="line-71"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>BasicTypes</span>
<a name="line-72"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>FastString</span>
<a name="line-73"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Outputable</span>
<a name="line-74"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Util</span>
<a name="line-75"></a>
<a name="line-76"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Word</span>
<a name="line-77"></a>
<a name="line-78"></a><span class='hs-keyword'>infixl</span> <span class='hs-num'>4</span> <span class='hs-varop'>`mkApps`</span><span class='hs-layout'>,</span> <span class='hs-varop'>`mkTyApps`</span><span class='hs-layout'>,</span> <span class='hs-varop'>`mkVarApps`</span>
<a name="line-79"></a><span class='hs-comment'>-- Left associative, so that we can say (f `mkTyApps` xs `mkVarApps` ys)</span>
</pre>\end{code}

%************************************************************************
%*									*
\subsection{The main data types}
%*									*
%************************************************************************

These data types are the heart of the compiler

\begin{code}
<pre><a name="line-1"></a><span class='hs-keyword'>infixl</span> <span class='hs-num'>8</span> <span class='hs-varop'>`App`</span>	<span class='hs-comment'>-- App brackets to the left</span>
<a name="line-2"></a>
<a name="line-3"></a><a name="Expr"></a><span class='hs-comment'>-- | This is the data type that represents GHCs core intermediate language. Currently</span>
<a name="line-4"></a><a name="Expr"></a><span class='hs-comment'>-- GHC uses System FC &lt;<a href="http://research.microsoft.com/~simonpj/papers/ext-f/">http://research.microsoft.com/~simonpj/papers/ext-f/</a>&gt; for this purpose,</span>
<a name="line-5"></a><a name="Expr"></a><span class='hs-comment'>-- which is closely related to the simpler and better known System F &lt;<a href="http://en.wikipedia.org/wiki/System_F">http://en.wikipedia.org/wiki/System_F</a>&gt;.</span>
<a name="line-6"></a><a name="Expr"></a><span class='hs-comment'>--</span>
<a name="line-7"></a><a name="Expr"></a><span class='hs-comment'>-- We get from Haskell source to this Core language in a number of stages:</span>
<a name="line-8"></a><a name="Expr"></a><span class='hs-comment'>--</span>
<a name="line-9"></a><a name="Expr"></a><span class='hs-comment'>-- 1. The source code is parsed into an abstract syntax tree, which is represented</span>
<a name="line-10"></a><a name="Expr"></a><span class='hs-comment'>--    by the data type 'HsExpr.HsExpr' with the names being 'RdrName.RdrNames'</span>
<a name="line-11"></a><a name="Expr"></a><span class='hs-comment'>--</span>
<a name="line-12"></a><a name="Expr"></a><span class='hs-comment'>-- 2. This syntax tree is /renamed/, which attaches a 'Unique.Unique' to every 'RdrName.RdrName'</span>
<a name="line-13"></a><a name="Expr"></a><span class='hs-comment'>--    (yielding a 'Name.Name') to disambiguate identifiers which are lexically identical. </span>
<a name="line-14"></a><a name="Expr"></a><span class='hs-comment'>--    For example, this program:</span>
<a name="line-15"></a><a name="Expr"></a><span class='hs-comment'>--</span>
<a name="line-16"></a><a name="Expr"></a><span class='hs-comment'>-- @</span>
<a name="line-17"></a><a name="Expr"></a><span class='hs-comment'>--      f x = let f x = x + 1</span>
<a name="line-18"></a><a name="Expr"></a><span class='hs-comment'>--            in f (x - 2)</span>
<a name="line-19"></a><a name="Expr"></a><span class='hs-comment'>-- @</span>
<a name="line-20"></a><a name="Expr"></a><span class='hs-comment'>--</span>
<a name="line-21"></a><a name="Expr"></a><span class='hs-comment'>--    Would be renamed by having 'Unique's attached so it looked something like this:</span>
<a name="line-22"></a><a name="Expr"></a><span class='hs-comment'>--</span>
<a name="line-23"></a><a name="Expr"></a><span class='hs-comment'>-- @</span>
<a name="line-24"></a><a name="Expr"></a><span class='hs-comment'>--      f_1 x_2 = let f_3 x_4 = x_4 + 1</span>
<a name="line-25"></a><a name="Expr"></a><span class='hs-comment'>--                in f_3 (x_2 - 2)</span>
<a name="line-26"></a><a name="Expr"></a><span class='hs-comment'>-- @</span>
<a name="line-27"></a><a name="Expr"></a><span class='hs-comment'>--</span>
<a name="line-28"></a><a name="Expr"></a><span class='hs-comment'>-- 3. The resulting syntax tree undergoes type checking (which also deals with instantiating</span>
<a name="line-29"></a><a name="Expr"></a><span class='hs-comment'>--    type class arguments) to yield a 'HsExpr.HsExpr' type that has 'Id.Id' as it's names.</span>
<a name="line-30"></a><a name="Expr"></a><span class='hs-comment'>--</span>
<a name="line-31"></a><a name="Expr"></a><span class='hs-comment'>-- 4. Finally the syntax tree is /desugared/ from the expressive 'HsExpr.HsExpr' type into</span>
<a name="line-32"></a><a name="Expr"></a><span class='hs-comment'>--    this 'Expr' type, which has far fewer constructors and hence is easier to perform</span>
<a name="line-33"></a><a name="Expr"></a><span class='hs-comment'>--    optimization, analysis and code generation on.</span>
<a name="line-34"></a><a name="Expr"></a><span class='hs-comment'>--</span>
<a name="line-35"></a><a name="Expr"></a><span class='hs-comment'>-- The type parameter @b@ is for the type of binders in the expression tree.</span>
<a name="line-36"></a><a name="Expr"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-37"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Var</span>	  <span class='hs-conid'>Id</span>                            <span class='hs-comment'>-- ^ Variables</span>
<a name="line-38"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Lit</span>   <span class='hs-conid'>Literal</span>                       <span class='hs-comment'>-- ^ Primitive literals</span>
<a name="line-39"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>App</span>   <span class='hs-layout'>(</span><span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>Arg</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span>		<span class='hs-comment'>-- ^ Applications: note that the argument may be a 'Type'.</span>
<a name="line-40"></a>                                        <span class='hs-comment'>--</span>
<a name="line-41"></a>                                        <span class='hs-comment'>-- See "CoreSyn#let_app_invariant" for another invariant</span>
<a name="line-42"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Lam</span>   <span class='hs-varid'>b</span> <span class='hs-layout'>(</span><span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span>                    <span class='hs-comment'>-- ^ Lambda abstraction</span>
<a name="line-43"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Let</span>   <span class='hs-layout'>(</span><span class='hs-conid'>Bind</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span>		<span class='hs-comment'>-- ^ Recursive and non recursive @let@s. Operationally</span>
<a name="line-44"></a>                                        <span class='hs-comment'>-- this corresponds to allocating a thunk for the things</span>
<a name="line-45"></a>                                        <span class='hs-comment'>-- bound and then executing the sub-expression.</span>
<a name="line-46"></a>                                        <span class='hs-comment'>-- </span>
<a name="line-47"></a>                                        <span class='hs-comment'>-- #top_level_invariant#</span>
<a name="line-48"></a>                                        <span class='hs-comment'>-- #letrec_invariant#</span>
<a name="line-49"></a>                                        <span class='hs-comment'>--</span>
<a name="line-50"></a>                                        <span class='hs-comment'>-- The right hand sides of all top-level and recursive @let@s</span>
<a name="line-51"></a>                                        <span class='hs-comment'>-- /must/ be of lifted type (see "Type#type_classification" for</span>
<a name="line-52"></a>                                        <span class='hs-comment'>-- the meaning of /lifted/ vs. /unlifted/).</span>
<a name="line-53"></a>                                        <span class='hs-comment'>--</span>
<a name="line-54"></a>                                        <span class='hs-comment'>-- #let_app_invariant#</span>
<a name="line-55"></a>                                        <span class='hs-comment'>-- The right hand side of of a non-recursive 'Let' _and_ the argument of an 'App',</span>
<a name="line-56"></a>                                        <span class='hs-comment'>-- /may/ be of unlifted type, but only if the expression </span>
<a name="line-57"></a>                                        <span class='hs-comment'>-- is ok-for-speculation.  This means that the let can be floated around </span>
<a name="line-58"></a>                                        <span class='hs-comment'>-- without difficulty. For example, this is OK:</span>
<a name="line-59"></a>                                        <span class='hs-comment'>--</span>
<a name="line-60"></a>	                                <span class='hs-comment'>-- &gt; y::Int# = x +# 1#</span>
<a name="line-61"></a>	                                <span class='hs-comment'>--</span>
<a name="line-62"></a>	                                <span class='hs-comment'>-- But this is not, as it may affect termination if the expression is floated out:</span>
<a name="line-63"></a>	                                <span class='hs-comment'>--</span>
<a name="line-64"></a>	                                <span class='hs-comment'>-- &gt; y::Int# = fac 4#</span>
<a name="line-65"></a>	                                <span class='hs-comment'>--</span>
<a name="line-66"></a>	                                <span class='hs-comment'>-- In this situation you should use @case@ rather than a @let@. The function</span>
<a name="line-67"></a>	                                <span class='hs-comment'>-- 'CoreUtils.needsCaseBinding' can help you determine which to generate, or</span>
<a name="line-68"></a>	                                <span class='hs-comment'>-- alternatively use 'MkCore.mkCoreLet' rather than this constructor directly,</span>
<a name="line-69"></a>	                                <span class='hs-comment'>-- which will generate a @case@ if necessary</span>
<a name="line-70"></a>	                                <span class='hs-comment'>--</span>
<a name="line-71"></a>	                                <span class='hs-comment'>-- #type_let#</span>
<a name="line-72"></a>	                                <span class='hs-comment'>-- We allow a /non-recursive/ let to bind a type variable, thus:</span>
<a name="line-73"></a>	                                <span class='hs-comment'>--</span>
<a name="line-74"></a>	                                <span class='hs-comment'>-- &gt; Let (NonRec tv (Type ty)) body</span>
<a name="line-75"></a>	                                <span class='hs-comment'>--</span>
<a name="line-76"></a>	                                <span class='hs-comment'>-- This can be very convenient for postponing type substitutions until</span>
<a name="line-77"></a>                                        <span class='hs-comment'>-- the next run of the simplifier.</span>
<a name="line-78"></a>                                        <span class='hs-comment'>--</span>
<a name="line-79"></a>                                        <span class='hs-comment'>-- At the moment, the rest of the compiler only deals with type-let</span>
<a name="line-80"></a>                                        <span class='hs-comment'>-- in a Let expression, rather than at top level.  We may want to revist</span>
<a name="line-81"></a>                                        <span class='hs-comment'>-- this choice.</span>
<a name="line-82"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Case</span>  <span class='hs-layout'>(</span><span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-varid'>b</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Alt</span> <span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span>  	<span class='hs-comment'>-- ^ Case split. Operationally this corresponds to evaluating</span>
<a name="line-83"></a>                                        <span class='hs-comment'>-- the scrutinee (expression examined) to weak head normal form</span>
<a name="line-84"></a>                                        <span class='hs-comment'>-- and then examining at most one level of resulting constructor (i.e. you</span>
<a name="line-85"></a>                                        <span class='hs-comment'>-- cannot do nested pattern matching directly with this).</span>
<a name="line-86"></a>                                        <span class='hs-comment'>--</span>
<a name="line-87"></a>                                        <span class='hs-comment'>-- The binder gets bound to the value of the scrutinee,</span>
<a name="line-88"></a>                                        <span class='hs-comment'>-- and the 'Type' must be that of all the case alternatives</span>
<a name="line-89"></a>					<span class='hs-comment'>--</span>
<a name="line-90"></a>					<span class='hs-comment'>-- #case_invariants#</span>
<a name="line-91"></a>					<span class='hs-comment'>-- This is one of the more complicated elements of the Core language, and comes</span>
<a name="line-92"></a>					<span class='hs-comment'>-- with a number of restrictions:</span>
<a name="line-93"></a>					<span class='hs-comment'>--</span>
<a name="line-94"></a>					<span class='hs-comment'>-- The 'DEFAULT' case alternative must be first in the list, if it occurs at all.</span>
<a name="line-95"></a>					<span class='hs-comment'>--</span>
<a name="line-96"></a>					<span class='hs-comment'>-- The remaining cases are in order of increasing </span>
<a name="line-97"></a>		                        <span class='hs-comment'>--      tag	(for 'DataAlts') or</span>
<a name="line-98"></a>		                        <span class='hs-comment'>--      lit	(for 'LitAlts').</span>
<a name="line-99"></a>	                                <span class='hs-comment'>-- This makes finding the relevant constructor easy, and makes comparison easier too.</span>
<a name="line-100"></a>					<span class='hs-comment'>--</span>
<a name="line-101"></a>					<span class='hs-comment'>-- The list of alternatives must be exhaustive. An /exhaustive/ case </span>
<a name="line-102"></a>					<span class='hs-comment'>-- does not necessarily mention all constructors:</span>
<a name="line-103"></a>					<span class='hs-comment'>--</span>
<a name="line-104"></a>					<span class='hs-comment'>-- @</span>
<a name="line-105"></a>                                        <span class='hs-comment'>--      data Foo = Red | Green | Blue</span>
<a name="line-106"></a>                                        <span class='hs-comment'>-- ... case x of </span>
<a name="line-107"></a>                                        <span class='hs-comment'>--      Red   -&gt; True</span>
<a name="line-108"></a>                                        <span class='hs-comment'>--      other -&gt; f (case x of </span>
<a name="line-109"></a>                                        <span class='hs-comment'>--                      Green -&gt; ...</span>
<a name="line-110"></a>                                        <span class='hs-comment'>--                      Blue  -&gt; ... ) ...</span>
<a name="line-111"></a>                                        <span class='hs-comment'>-- @</span>
<a name="line-112"></a>                                        <span class='hs-comment'>--</span>
<a name="line-113"></a>                                        <span class='hs-comment'>-- The inner case does not need a @Red@ alternative, because @x@ can't be @Red@ at</span>
<a name="line-114"></a>                                        <span class='hs-comment'>-- that program point.</span>
<a name="line-115"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Cast</span>  <span class='hs-layout'>(</span><span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-conid'>Coercion</span>             <span class='hs-comment'>-- ^ Cast an expression to a particular type. This is used to implement @newtype@s</span>
<a name="line-116"></a>                                        <span class='hs-comment'>-- (a @newtype@ constructor or destructor just becomes a 'Cast' in Core) and GADTs.</span>
<a name="line-117"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Note</span>  <span class='hs-conid'>Note</span> <span class='hs-layout'>(</span><span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span>                 <span class='hs-comment'>-- ^ Notes. These allow general information to be</span>
<a name="line-118"></a>                                        <span class='hs-comment'>-- added to expressions in the syntax tree</span>
<a name="line-119"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Type</span>  <span class='hs-conid'>Type</span>			        <span class='hs-comment'>-- ^ A type: this should only show up at the top</span>
<a name="line-120"></a>                                        <span class='hs-comment'>-- level of an Arg</span>
<a name="line-121"></a>
<a name="line-122"></a><a name="Arg"></a><span class='hs-comment'>-- | Type synonym for expressions that occur in function argument positions.</span>
<a name="line-123"></a><a name="Arg"></a><span class='hs-comment'>-- Only 'Arg' should contain a 'Type' at top level, general 'Expr' should not</span>
<a name="line-124"></a><a name="Arg"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>Arg</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-125"></a>
<a name="line-126"></a><a name="Alt"></a><span class='hs-comment'>-- | A case split alternative. Consists of the constructor leading to the alternative,</span>
<a name="line-127"></a><a name="Alt"></a><span class='hs-comment'>-- the variables bound from the constructor, and the expression to be executed given that binding.</span>
<a name="line-128"></a><a name="Alt"></a><span class='hs-comment'>-- The default alternative is @(DEFAULT, [], rhs)@</span>
<a name="line-129"></a><a name="Alt"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>Alt</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>AltCon</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span>
<a name="line-130"></a>
<a name="line-131"></a><a name="AltCon"></a><span class='hs-comment'>-- | A case alternative constructor (i.e. pattern match)</span>
<a name="line-132"></a><a name="AltCon"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>AltCon</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>DataAlt</span> <span class='hs-conid'>DataCon</span>	<span class='hs-comment'>-- ^ A plain data constructor: @case e of { Foo x -&gt; ... }@.</span>
<a name="line-133"></a>                                <span class='hs-comment'>-- Invariant: the 'DataCon' is always from a @data@ type, and never from a @newtype@</span>
<a name="line-134"></a>	    <span class='hs-keyglyph'>|</span> <span class='hs-conid'>LitAlt</span>  <span class='hs-conid'>Literal</span>   <span class='hs-comment'>-- ^ A literal: @case e of { 1 -&gt; ... }@</span>
<a name="line-135"></a>	    <span class='hs-keyglyph'>|</span> <span class='hs-conid'>DEFAULT</span>           <span class='hs-comment'>-- ^ Trivial alternative: @case e of { _ -&gt; ... }@</span>
<a name="line-136"></a>	 <span class='hs-keyword'>deriving</span> <span class='hs-layout'>(</span><span class='hs-conid'>Eq</span><span class='hs-layout'>,</span> <span class='hs-conid'>Ord</span><span class='hs-layout'>)</span>
<a name="line-137"></a>
<a name="line-138"></a><a name="Bind"></a><span class='hs-comment'>-- | Binding, used for top level bindings in a module and local bindings in a @let@.</span>
<a name="line-139"></a><a name="Bind"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Bind</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NonRec</span> <span class='hs-varid'>b</span> <span class='hs-layout'>(</span><span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span>
<a name="line-140"></a>	    <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Rec</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-layout'>,</span> <span class='hs-layout'>(</span><span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span>
</pre>\end{code}

-------------------------- CoreSyn INVARIANTS ---------------------------

Note [CoreSyn top-level invariant]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See #toplevel_invariant#

Note [CoreSyn letrec invariant]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See #letrec_invariant#

Note [CoreSyn let/app invariant]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See #let_app_invariant#

This is intially enforced by DsUtils.mkCoreLet and mkCoreApp

Note [CoreSyn case invariants]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See #case_invariants#

Note [CoreSyn let goal]
~~~~~~~~~~~~~~~~~~~~~~~
* The simplifier tries to ensure that if the RHS of a let is a constructor
  application, its arguments are trivial, so that the constructor can be
  inlined vigorously.


Note [Type let]
~~~~~~~~~~~~~~~
See #type_let#

\begin{code}
<pre><a name="line-1"></a>
<a name="line-2"></a><a name="Note"></a><span class='hs-comment'>-- | Allows attaching extra information to points in expressions rather than e.g. identifiers.</span>
<a name="line-3"></a><a name="Note"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Note</span>
<a name="line-4"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>SCC</span> <span class='hs-conid'>CostCentre</span>      <span class='hs-comment'>-- ^ A cost centre annotation for profiling</span>
<a name="line-5"></a>
<a name="line-6"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>InlineMe</span>		<span class='hs-comment'>-- ^ Instructs the core simplifer to treat the enclosed expression</span>
<a name="line-7"></a>			<span class='hs-comment'>-- as very small, and inline it at its call sites</span>
<a name="line-8"></a>
<a name="line-9"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>CoreNote</span> <span class='hs-conid'>String</span>     <span class='hs-comment'>-- ^ A generic core annotation, propagated but not used by GHC</span>
<a name="line-10"></a>
<a name="line-11"></a><span class='hs-comment'>-- NOTE: we also treat expressions wrapped in InlineMe as</span>
<a name="line-12"></a><span class='hs-comment'>-- 'cheap' and 'dupable' (in the sense of exprIsCheap, exprIsDupable)</span>
<a name="line-13"></a><span class='hs-comment'>-- What this means is that we obediently inline even things that don't</span>
<a name="line-14"></a><span class='hs-comment'>-- look like valuse.  This is sometimes important:</span>
<a name="line-15"></a><span class='hs-comment'>--	{-# INLINE f #-}</span>
<a name="line-16"></a><span class='hs-comment'>--	f = g . h</span>
<a name="line-17"></a><span class='hs-comment'>-- Here, f looks like a redex, and we aren't going to inline (.) because it's</span>
<a name="line-18"></a><span class='hs-comment'>-- inside an INLINE, so it'll stay looking like a redex.  Nevertheless, we </span>
<a name="line-19"></a><span class='hs-comment'>-- should inline f even inside lambdas.  In effect, we should trust the programmer.</span>
</pre>\end{code}


%************************************************************************
%*									*
\subsection{Transformation rules}
%*									*
%************************************************************************

The CoreRule type and its friends are dealt with mainly in CoreRules,
but CoreFVs, Subst, PprCore, CoreTidy also inspect the representation.

\begin{code}
<pre><a name="line-1"></a><a name="CoreRule"></a><span class='hs-comment'>-- | A 'CoreRule' is:</span>
<a name="line-2"></a><a name="CoreRule"></a><span class='hs-comment'>--</span>
<a name="line-3"></a><a name="CoreRule"></a><span class='hs-comment'>-- * \"Local\" if the function it is a rule for is defined in the</span>
<a name="line-4"></a><a name="CoreRule"></a><span class='hs-comment'>--   same module as the rule itself.</span>
<a name="line-5"></a><a name="CoreRule"></a><span class='hs-comment'>--</span>
<a name="line-6"></a><a name="CoreRule"></a><span class='hs-comment'>-- * \"Orphan\" if nothing on the LHS is defined in the same module</span>
<a name="line-7"></a><a name="CoreRule"></a><span class='hs-comment'>--   as the rule itself</span>
<a name="line-8"></a><a name="CoreRule"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>CoreRule</span>
<a name="line-9"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Rule</span> <span class='hs-layout'>{</span> 
<a name="line-10"></a>	<span class='hs-varid'>ru_name</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RuleName</span><span class='hs-layout'>,</span>            <span class='hs-comment'>-- ^ Name of the rule, for communication with the user</span>
<a name="line-11"></a>	<span class='hs-varid'>ru_act</span>  <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Activation</span><span class='hs-layout'>,</span>          <span class='hs-comment'>-- ^ When the rule is active</span>
<a name="line-12"></a>	
<a name="line-13"></a>	<span class='hs-comment'>-- Rough-matching stuff</span>
<a name="line-14"></a>	<span class='hs-comment'>-- see comments with InstEnv.Instance( is_cls, is_rough )</span>
<a name="line-15"></a>	<span class='hs-varid'>ru_fn</span>    <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Name</span><span class='hs-layout'>,</span>	        <span class='hs-comment'>-- ^ Name of the 'Id.Id' at the head of this rule</span>
<a name="line-16"></a>	<span class='hs-varid'>ru_rough</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Maybe</span> <span class='hs-conid'>Name</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span>	<span class='hs-comment'>-- ^ Name at the head of each argument to the left hand side</span>
<a name="line-17"></a>	
<a name="line-18"></a>	<span class='hs-comment'>-- Proper-matching stuff</span>
<a name="line-19"></a>	<span class='hs-comment'>-- see comments with InstEnv.Instance( is_tvs, is_tys )</span>
<a name="line-20"></a>	<span class='hs-varid'>ru_bndrs</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreBndr</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span>         <span class='hs-comment'>-- ^ Variables quantified over</span>
<a name="line-21"></a>	<span class='hs-varid'>ru_args</span>  <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreExpr</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span>         <span class='hs-comment'>-- ^ Left hand side arguments</span>
<a name="line-22"></a>	
<a name="line-23"></a>	<span class='hs-comment'>-- And the right-hand side</span>
<a name="line-24"></a>	<span class='hs-varid'>ru_rhs</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreExpr</span><span class='hs-layout'>,</span>           <span class='hs-comment'>-- ^ Right hand side of the rule</span>
<a name="line-25"></a>
<a name="line-26"></a>	<span class='hs-comment'>-- Locality</span>
<a name="line-27"></a>	<span class='hs-varid'>ru_local</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span>	<span class='hs-comment'>-- ^ @True@ iff the fn at the head of the rule is</span>
<a name="line-28"></a>				<span class='hs-comment'>-- defined in the same module as the rule</span>
<a name="line-29"></a>				<span class='hs-comment'>-- and is not an implicit 'Id' (like a record selector,</span>
<a name="line-30"></a>				<span class='hs-comment'>-- class operation, or data constructor)</span>
<a name="line-31"></a>
<a name="line-32"></a>		<span class='hs-comment'>-- NB: ru_local is *not* used to decide orphan-hood</span>
<a name="line-33"></a>		<span class='hs-comment'>--	c.g. MkIface.coreRuleToIfaceRule</span>
<a name="line-34"></a>    <span class='hs-layout'>}</span>
<a name="line-35"></a>
<a name="line-36"></a>  <span class='hs-comment'>-- | Built-in rules are used for constant folding</span>
<a name="line-37"></a>  <span class='hs-comment'>-- and suchlike.  They have no free variables.</span>
<a name="line-38"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>BuiltinRule</span> <span class='hs-layout'>{</span>               
<a name="line-39"></a>	<span class='hs-varid'>ru_name</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RuleName</span><span class='hs-layout'>,</span>    <span class='hs-comment'>-- ^ As above</span>
<a name="line-40"></a>	<span class='hs-varid'>ru_fn</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Name</span><span class='hs-layout'>,</span>          <span class='hs-comment'>-- ^ As above</span>
<a name="line-41"></a>	<span class='hs-varid'>ru_nargs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span><span class='hs-layout'>,</span>	<span class='hs-comment'>-- ^ Number of arguments that 'ru_try' expects,</span>
<a name="line-42"></a>				<span class='hs-comment'>-- including type arguments</span>
<a name="line-43"></a>	<span class='hs-varid'>ru_try</span>  <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreExpr</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-conid'>CoreExpr</span>
<a name="line-44"></a>		<span class='hs-comment'>-- ^ This function does the rewrite.  It given too many</span>
<a name="line-45"></a>		<span class='hs-comment'>-- arguments, it simply discards them; the returned 'CoreExpr'</span>
<a name="line-46"></a>		<span class='hs-comment'>-- is just the rewrite of 'ru_fn' applied to the first 'ru_nargs' args</span>
<a name="line-47"></a>    <span class='hs-layout'>}</span>
<a name="line-48"></a>		<span class='hs-comment'>-- See Note [Extra args in rule matching] in Rules.lhs</span>
<a name="line-49"></a>
<a name="line-50"></a><a name="isBuiltinRule"></a><span class='hs-definition'>isBuiltinRule</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreRule</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-51"></a><span class='hs-definition'>isBuiltinRule</span> <span class='hs-layout'>(</span><span class='hs-conid'>BuiltinRule</span> <span class='hs-layout'>{</span><span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-52"></a><span class='hs-definition'>isBuiltinRule</span> <span class='hs-keyword'>_</span>		       <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-53"></a>
<a name="line-54"></a><a name="ruleArity"></a><span class='hs-comment'>-- | The number of arguments the 'ru_fn' must be applied </span>
<a name="line-55"></a><span class='hs-comment'>-- to before the rule can match on it</span>
<a name="line-56"></a><span class='hs-definition'>ruleArity</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreRule</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
<a name="line-57"></a><span class='hs-definition'>ruleArity</span> <span class='hs-layout'>(</span><span class='hs-conid'>BuiltinRule</span> <span class='hs-layout'>{</span><span class='hs-varid'>ru_nargs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>n</span><span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>n</span>
<a name="line-58"></a><span class='hs-definition'>ruleArity</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rule</span> <span class='hs-layout'>{</span><span class='hs-varid'>ru_args</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>args</span><span class='hs-layout'>}</span><span class='hs-layout'>)</span>      <span class='hs-keyglyph'>=</span> <span class='hs-varid'>length</span> <span class='hs-varid'>args</span>
<a name="line-59"></a>
<a name="line-60"></a><a name="ruleName"></a><span class='hs-definition'>ruleName</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreRule</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RuleName</span>
<a name="line-61"></a><span class='hs-definition'>ruleName</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ru_name</span>
<a name="line-62"></a>
<a name="line-63"></a><a name="ruleActivation_maybe"></a><span class='hs-definition'>ruleActivation_maybe</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreRule</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-conid'>Activation</span>
<a name="line-64"></a><span class='hs-definition'>ruleActivation_maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>BuiltinRule</span> <span class='hs-layout'>{</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span>       <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
<a name="line-65"></a><span class='hs-definition'>ruleActivation_maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rule</span> <span class='hs-layout'>{</span> <span class='hs-varid'>ru_act</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>act</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>act</span>
<a name="line-66"></a>
<a name="line-67"></a><a name="ruleIdName"></a><span class='hs-comment'>-- | The 'Name' of the 'Id.Id' at the head of the rule left hand side</span>
<a name="line-68"></a><span class='hs-definition'>ruleIdName</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreRule</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Name</span>
<a name="line-69"></a><span class='hs-definition'>ruleIdName</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ru_fn</span>
<a name="line-70"></a>
<a name="line-71"></a><a name="isLocalRule"></a><span class='hs-definition'>isLocalRule</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreRule</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-72"></a><span class='hs-definition'>isLocalRule</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ru_local</span>
<a name="line-73"></a>
<a name="line-74"></a><a name="setRuleIdName"></a><span class='hs-comment'>-- | Set the 'Name' of the 'Id.Id' at the head of the rule left hand side</span>
<a name="line-75"></a><span class='hs-definition'>setRuleIdName</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Name</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoreRule</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoreRule</span>
<a name="line-76"></a><span class='hs-definition'>setRuleIdName</span> <span class='hs-varid'>nm</span> <span class='hs-varid'>ru</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ru</span> <span class='hs-layout'>{</span> <span class='hs-varid'>ru_fn</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nm</span> <span class='hs-layout'>}</span>
</pre>\end{code}


%************************************************************************
%*									*
		Unfoldings
%*									*
%************************************************************************

The @Unfolding@ type is declared here to avoid numerous loops

\begin{code}
<pre><a name="line-1"></a><a name="Unfolding"></a><span class='hs-comment'>-- | Records the /unfolding/ of an identifier, which is approximately the form the</span>
<a name="line-2"></a><a name="Unfolding"></a><span class='hs-comment'>-- identifier would have if we substituted its definition in for the identifier.</span>
<a name="line-3"></a><a name="Unfolding"></a><span class='hs-comment'>-- This type should be treated as abstract everywhere except in "CoreUnfold"</span>
<a name="line-4"></a><a name="Unfolding"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Unfolding</span>
<a name="line-5"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NoUnfolding</span>                 <span class='hs-comment'>-- ^ We have no information about the unfolding</span>
<a name="line-6"></a>
<a name="line-7"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>OtherCon</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>AltCon</span><span class='hs-keyglyph'>]</span>		<span class='hs-comment'>-- ^ It ain't one of these constructors.</span>
<a name="line-8"></a>				<span class='hs-comment'>-- @OtherCon xs@ also indicates that something has been evaluated</span>
<a name="line-9"></a>				<span class='hs-comment'>-- and hence there's no point in re-evaluating it.</span>
<a name="line-10"></a>				<span class='hs-comment'>-- @OtherCon []@ is used even for non-data-type values</span>
<a name="line-11"></a>				<span class='hs-comment'>-- to indicated evaluated-ness.  Notably:</span>
<a name="line-12"></a>				<span class='hs-comment'>--</span>
<a name="line-13"></a>				<span class='hs-comment'>-- &gt; data C = C !(Int -&gt; Int)</span>
<a name="line-14"></a>				<span class='hs-comment'>-- &gt; case x of { C f -&gt; ... }</span>
<a name="line-15"></a>				<span class='hs-comment'>--</span>
<a name="line-16"></a>				<span class='hs-comment'>-- Here, @f@ gets an @OtherCon []@ unfolding.</span>
<a name="line-17"></a>
<a name="line-18"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>CompulsoryUnfolding</span> <span class='hs-conid'>CoreExpr</span>	<span class='hs-comment'>-- ^ There is /no original definition/,</span>
<a name="line-19"></a>					<span class='hs-comment'>-- so you'd better unfold.</span>
<a name="line-20"></a>
<a name="line-21"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>CoreUnfolding</span>
<a name="line-22"></a>		<span class='hs-conid'>CoreExpr</span>
<a name="line-23"></a>		<span class='hs-conid'>Bool</span>
<a name="line-24"></a>		<span class='hs-conid'>Bool</span>
<a name="line-25"></a>		<span class='hs-conid'>Bool</span>
<a name="line-26"></a>                <span class='hs-conid'>Bool</span>
<a name="line-27"></a>		<span class='hs-conid'>UnfoldingGuidance</span>
<a name="line-28"></a>  <span class='hs-comment'>-- ^ An unfolding with redundant cached information. Parameters:</span>
<a name="line-29"></a>  <span class='hs-comment'>--</span>
<a name="line-30"></a>  <span class='hs-comment'>--  1) Template used to perform unfolding; binder-info is correct</span>
<a name="line-31"></a>  <span class='hs-comment'>--</span>
<a name="line-32"></a>  <span class='hs-comment'>--  2) Is this a top level binding?</span>
<a name="line-33"></a>  <span class='hs-comment'>--</span>
<a name="line-34"></a>  <span class='hs-comment'>--  3) 'exprIsHNF' template (cached); it is ok to discard a 'seq' on</span>
<a name="line-35"></a>  <span class='hs-comment'>--     this variable</span>
<a name="line-36"></a>  <span class='hs-comment'>--</span>
<a name="line-37"></a>  <span class='hs-comment'>--  4) Does this waste only a little work if we expand it inside an inlining?</span>
<a name="line-38"></a>  <span class='hs-comment'>--     Basically this is a cached version of 'exprIsCheap'</span>
<a name="line-39"></a>  <span class='hs-comment'>--</span>
<a name="line-40"></a>  <span class='hs-comment'>--  5) Tells us about the /size/ of the unfolding template</span>
<a name="line-41"></a>
<a name="line-42"></a><a name="UnfoldingGuidance"></a><span class='hs-comment'>-- | When unfolding should take place</span>
<a name="line-43"></a><a name="UnfoldingGuidance"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>UnfoldingGuidance</span>
<a name="line-44"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>UnfoldNever</span>
<a name="line-45"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>UnfoldIfGoodArgs</span>	<span class='hs-conid'>Int</span>	<span class='hs-comment'>-- and "n" value args</span>
<a name="line-46"></a>
<a name="line-47"></a>			<span class='hs-keyglyph'>[</span><span class='hs-conid'>Int</span><span class='hs-keyglyph'>]</span>	<span class='hs-comment'>-- Discount if the argument is evaluated.</span>
<a name="line-48"></a>				<span class='hs-comment'>-- (i.e., a simplification will definitely</span>
<a name="line-49"></a>				<span class='hs-comment'>-- be possible).  One elt of the list per *value* arg.</span>
<a name="line-50"></a>
<a name="line-51"></a>			<span class='hs-conid'>Int</span>	<span class='hs-comment'>-- The "size" of the unfolding; to be elaborated</span>
<a name="line-52"></a>				<span class='hs-comment'>-- later. ToDo</span>
<a name="line-53"></a>
<a name="line-54"></a>			<span class='hs-conid'>Int</span>	<span class='hs-comment'>-- Scrutinee discount: the discount to substract if the thing is in</span>
<a name="line-55"></a>				<span class='hs-comment'>-- a context (case (thing args) of ...),</span>
<a name="line-56"></a>				<span class='hs-comment'>-- (where there are the right number of arguments.)</span>
<a name="line-57"></a>
<a name="line-58"></a><a name="noUnfolding"></a><span class='hs-definition'>noUnfolding</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Unfolding</span>
<a name="line-59"></a><a name="evaldUnfolding"></a><span class='hs-comment'>-- ^ There is no known 'Unfolding'</span>
<a name="line-60"></a><span class='hs-definition'>evaldUnfolding</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Unfolding</span>
<a name="line-61"></a><span class='hs-comment'>-- ^ This unfolding marks the associated thing as being evaluated</span>
<a name="line-62"></a>
<a name="line-63"></a><span class='hs-definition'>noUnfolding</span>    <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NoUnfolding</span>
<a name="line-64"></a><span class='hs-definition'>evaldUnfolding</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>OtherCon</span> <span class='hs-conid'>[]</span>
<a name="line-65"></a>
<a name="line-66"></a><a name="mkOtherCon"></a><span class='hs-definition'>mkOtherCon</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>AltCon</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Unfolding</span>
<a name="line-67"></a><span class='hs-definition'>mkOtherCon</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>OtherCon</span>
<a name="line-68"></a>
<a name="line-69"></a><a name="seqUnfolding"></a><span class='hs-definition'>seqUnfolding</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Unfolding</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>()</span>
<a name="line-70"></a><span class='hs-definition'>seqUnfolding</span> <span class='hs-layout'>(</span><span class='hs-conid'>CoreUnfolding</span> <span class='hs-varid'>e</span> <span class='hs-varid'>top</span> <span class='hs-varid'>b1</span> <span class='hs-varid'>b2</span> <span class='hs-varid'>b3</span> <span class='hs-varid'>g</span><span class='hs-layout'>)</span>
<a name="line-71"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>seqExpr</span> <span class='hs-varid'>e</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>top</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>b1</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>b2</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>b3</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqGuidance</span> <span class='hs-varid'>g</span>
<a name="line-72"></a><span class='hs-definition'>seqUnfolding</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>()</span>
<a name="line-73"></a>
<a name="line-74"></a><a name="seqGuidance"></a><span class='hs-definition'>seqGuidance</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>UnfoldingGuidance</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>()</span>
<a name="line-75"></a><span class='hs-definition'>seqGuidance</span> <span class='hs-layout'>(</span><span class='hs-conid'>UnfoldIfGoodArgs</span> <span class='hs-varid'>n</span> <span class='hs-varid'>ns</span> <span class='hs-varid'>a</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>n</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>sum</span> <span class='hs-varid'>ns</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>a</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>b</span> <span class='hs-varop'>`seq`</span> <span class='hs-conid'>()</span>
<a name="line-76"></a><span class='hs-definition'>seqGuidance</span> <span class='hs-keyword'>_</span>                           <span class='hs-keyglyph'>=</span> <span class='hs-conid'>()</span>
</pre>\end{code}

\begin{code}
<pre><a name="line-1"></a><a name="unfoldingTemplate"></a><span class='hs-comment'>-- | Retrieves the template of an unfolding: panics if none is known</span>
<a name="line-2"></a><span class='hs-definition'>unfoldingTemplate</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Unfolding</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoreExpr</span>
<a name="line-3"></a><span class='hs-definition'>unfoldingTemplate</span> <span class='hs-layout'>(</span><span class='hs-conid'>CoreUnfolding</span> <span class='hs-varid'>expr</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>expr</span>
<a name="line-4"></a><span class='hs-definition'>unfoldingTemplate</span> <span class='hs-layout'>(</span><span class='hs-conid'>CompulsoryUnfolding</span> <span class='hs-varid'>expr</span><span class='hs-layout'>)</span>     <span class='hs-keyglyph'>=</span> <span class='hs-varid'>expr</span>
<a name="line-5"></a><span class='hs-definition'>unfoldingTemplate</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"getUnfoldingTemplate"</span>
<a name="line-6"></a>
<a name="line-7"></a><a name="maybeUnfoldingTemplate"></a><span class='hs-comment'>-- | Retrieves the template of an unfolding if possible</span>
<a name="line-8"></a><span class='hs-definition'>maybeUnfoldingTemplate</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Unfolding</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-conid'>CoreExpr</span>
<a name="line-9"></a><span class='hs-definition'>maybeUnfoldingTemplate</span> <span class='hs-layout'>(</span><span class='hs-conid'>CoreUnfolding</span> <span class='hs-varid'>expr</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>expr</span>
<a name="line-10"></a><span class='hs-definition'>maybeUnfoldingTemplate</span> <span class='hs-layout'>(</span><span class='hs-conid'>CompulsoryUnfolding</span> <span class='hs-varid'>expr</span><span class='hs-layout'>)</span>     <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>expr</span>
<a name="line-11"></a><span class='hs-definition'>maybeUnfoldingTemplate</span> <span class='hs-keyword'>_</span>                              <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
<a name="line-12"></a>
<a name="line-13"></a><a name="otherCons"></a><span class='hs-comment'>-- | The constructors that the unfolding could never be: </span>
<a name="line-14"></a><span class='hs-comment'>-- returns @[]@ if no information is available</span>
<a name="line-15"></a><span class='hs-definition'>otherCons</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Unfolding</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>AltCon</span><span class='hs-keyglyph'>]</span>
<a name="line-16"></a><span class='hs-definition'>otherCons</span> <span class='hs-layout'>(</span><span class='hs-conid'>OtherCon</span> <span class='hs-varid'>cons</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cons</span>
<a name="line-17"></a><span class='hs-definition'>otherCons</span> <span class='hs-keyword'>_</span>               <span class='hs-keyglyph'>=</span> <span class='hs-conid'>[]</span>
<a name="line-18"></a>
<a name="line-19"></a><a name="isValueUnfolding"></a><span class='hs-comment'>-- | Determines if it is certainly the case that the unfolding will</span>
<a name="line-20"></a><span class='hs-comment'>-- yield a value (something in HNF): returns @False@ if unsure</span>
<a name="line-21"></a><span class='hs-definition'>isValueUnfolding</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Unfolding</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-22"></a><span class='hs-definition'>isValueUnfolding</span> <span class='hs-layout'>(</span><span class='hs-conid'>CoreUnfolding</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>is_evald</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>is_evald</span>
<a name="line-23"></a><span class='hs-definition'>isValueUnfolding</span> <span class='hs-keyword'>_</span>                                  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-24"></a>
<a name="line-25"></a><a name="isEvaldUnfolding"></a><span class='hs-comment'>-- | Determines if it possibly the case that the unfolding will</span>
<a name="line-26"></a><span class='hs-comment'>-- yield a value. Unlike 'isValueUnfolding' it returns @True@</span>
<a name="line-27"></a><span class='hs-comment'>-- for 'OtherCon'</span>
<a name="line-28"></a><span class='hs-definition'>isEvaldUnfolding</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Unfolding</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-29"></a><span class='hs-definition'>isEvaldUnfolding</span> <span class='hs-layout'>(</span><span class='hs-conid'>OtherCon</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>		            <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-30"></a><span class='hs-definition'>isEvaldUnfolding</span> <span class='hs-layout'>(</span><span class='hs-conid'>CoreUnfolding</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>is_evald</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>is_evald</span>
<a name="line-31"></a><span class='hs-definition'>isEvaldUnfolding</span> <span class='hs-keyword'>_</span>                                  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-32"></a>
<a name="line-33"></a><a name="isCheapUnfolding"></a><span class='hs-comment'>-- | Is the thing we will unfold into certainly cheap?</span>
<a name="line-34"></a><span class='hs-definition'>isCheapUnfolding</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Unfolding</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-35"></a><span class='hs-definition'>isCheapUnfolding</span> <span class='hs-layout'>(</span><span class='hs-conid'>CoreUnfolding</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>is_cheap</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>is_cheap</span>
<a name="line-36"></a><span class='hs-definition'>isCheapUnfolding</span> <span class='hs-keyword'>_</span>                                  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-37"></a>
<a name="line-38"></a><a name="isExpandableUnfolding"></a><span class='hs-definition'>isExpandableUnfolding</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Unfolding</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-39"></a><span class='hs-definition'>isExpandableUnfolding</span> <span class='hs-layout'>(</span><span class='hs-conid'>CoreUnfolding</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>is_expable</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>is_expable</span>
<a name="line-40"></a><span class='hs-definition'>isExpandableUnfolding</span> <span class='hs-keyword'>_</span>                                    <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-41"></a>
<a name="line-42"></a><a name="isCompulsoryUnfolding"></a><span class='hs-comment'>-- | Must this unfolding happen for the code to be executable?</span>
<a name="line-43"></a><span class='hs-definition'>isCompulsoryUnfolding</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Unfolding</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-44"></a><span class='hs-definition'>isCompulsoryUnfolding</span> <span class='hs-layout'>(</span><span class='hs-conid'>CompulsoryUnfolding</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-45"></a><span class='hs-definition'>isCompulsoryUnfolding</span> <span class='hs-keyword'>_</span>                       <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-46"></a>
<a name="line-47"></a><a name="hasUnfolding"></a><span class='hs-comment'>-- | Do we have an available or compulsory unfolding?</span>
<a name="line-48"></a><span class='hs-definition'>hasUnfolding</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Unfolding</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-49"></a><span class='hs-definition'>hasUnfolding</span> <span class='hs-layout'>(</span><span class='hs-conid'>CoreUnfolding</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-50"></a><span class='hs-definition'>hasUnfolding</span> <span class='hs-layout'>(</span><span class='hs-conid'>CompulsoryUnfolding</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>     <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-51"></a><span class='hs-definition'>hasUnfolding</span> <span class='hs-keyword'>_</span>                           <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-52"></a>
<a name="line-53"></a><a name="hasSomeUnfolding"></a><span class='hs-comment'>-- | Only returns False if there is no unfolding information available at all</span>
<a name="line-54"></a><span class='hs-definition'>hasSomeUnfolding</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Unfolding</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-55"></a><span class='hs-definition'>hasSomeUnfolding</span> <span class='hs-conid'>NoUnfolding</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-56"></a><span class='hs-definition'>hasSomeUnfolding</span> <span class='hs-keyword'>_</span>           <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-57"></a>
<a name="line-58"></a><a name="neverUnfold"></a><span class='hs-comment'>-- | Similar to @not . hasUnfolding@, but also returns @True@</span>
<a name="line-59"></a><span class='hs-comment'>-- if it has an unfolding that says it should never occur</span>
<a name="line-60"></a><span class='hs-definition'>neverUnfold</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Unfolding</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-61"></a><span class='hs-definition'>neverUnfold</span> <span class='hs-conid'>NoUnfolding</span>				  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-62"></a><span class='hs-definition'>neverUnfold</span> <span class='hs-layout'>(</span><span class='hs-conid'>OtherCon</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>			  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-63"></a><span class='hs-definition'>neverUnfold</span> <span class='hs-layout'>(</span><span class='hs-conid'>CoreUnfolding</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>UnfoldNever</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-64"></a><span class='hs-definition'>neverUnfold</span> <span class='hs-keyword'>_</span>                                     <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
</pre>\end{code}


%************************************************************************
%*									*
\subsection{The main data type}
%*									*
%************************************************************************

\begin{code}
<pre><a name="line-1"></a><span class='hs-comment'>-- The Ord is needed for the FiniteMap used in the lookForConstructor</span>
<a name="line-2"></a><span class='hs-comment'>-- in SimplEnv.  If you declared that lookForConstructor *ignores*</span>
<a name="line-3"></a><span class='hs-comment'>-- constructor-applications with LitArg args, then you could get</span>
<a name="line-4"></a><span class='hs-comment'>-- rid of this Ord.</span>
<a name="line-5"></a>
<a name="line-6"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Outputable</span> <span class='hs-conid'>AltCon</span> <span class='hs-keyword'>where</span>
<a name="line-7"></a>  <span class='hs-varid'>ppr</span> <span class='hs-layout'>(</span><span class='hs-conid'>DataAlt</span> <span class='hs-varid'>dc</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>dc</span>
<a name="line-8"></a>  <span class='hs-varid'>ppr</span> <span class='hs-layout'>(</span><span class='hs-conid'>LitAlt</span> <span class='hs-varid'>lit</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>lit</span>
<a name="line-9"></a>  <span class='hs-varid'>ppr</span> <span class='hs-conid'>DEFAULT</span>      <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ptext</span> <span class='hs-layout'>(</span><span class='hs-varid'>sLit</span> <span class='hs-str'>"__DEFAULT"</span><span class='hs-layout'>)</span>
<a name="line-10"></a>
<a name="line-11"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Show</span> <span class='hs-conid'>AltCon</span> <span class='hs-keyword'>where</span>
<a name="line-12"></a>  <span class='hs-varid'>showsPrec</span> <span class='hs-varid'>p</span> <span class='hs-varid'>con</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>showsPrecSDoc</span> <span class='hs-varid'>p</span> <span class='hs-layout'>(</span><span class='hs-varid'>ppr</span> <span class='hs-varid'>con</span><span class='hs-layout'>)</span>
<a name="line-13"></a>
<a name="line-14"></a><a name="cmpAlt"></a><span class='hs-definition'>cmpAlt</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Alt</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Alt</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Ordering</span>
<a name="line-15"></a><span class='hs-definition'>cmpAlt</span> <span class='hs-layout'>(</span><span class='hs-varid'>con1</span><span class='hs-layout'>,</span> <span class='hs-keyword'>_</span><span class='hs-layout'>,</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>con2</span><span class='hs-layout'>,</span> <span class='hs-keyword'>_</span><span class='hs-layout'>,</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>con1</span> <span class='hs-varop'>`cmpAltCon`</span> <span class='hs-varid'>con2</span>
<a name="line-16"></a>
<a name="line-17"></a><a name="ltAlt"></a><span class='hs-definition'>ltAlt</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Alt</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Alt</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-18"></a><span class='hs-definition'>ltAlt</span> <span class='hs-varid'>a1</span> <span class='hs-varid'>a2</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>a1</span> <span class='hs-varop'>`cmpAlt`</span> <span class='hs-varid'>a2</span><span class='hs-layout'>)</span> <span class='hs-varop'>==</span> <span class='hs-conid'>LT</span>
<a name="line-19"></a>
<a name="line-20"></a><a name="cmpAltCon"></a><span class='hs-definition'>cmpAltCon</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>AltCon</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>AltCon</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Ordering</span>
<a name="line-21"></a><span class='hs-comment'>-- ^ Compares 'AltCon's within a single list of alternatives</span>
<a name="line-22"></a><span class='hs-definition'>cmpAltCon</span> <span class='hs-conid'>DEFAULT</span>      <span class='hs-conid'>DEFAULT</span>	   <span class='hs-keyglyph'>=</span> <span class='hs-conid'>EQ</span>
<a name="line-23"></a><span class='hs-definition'>cmpAltCon</span> <span class='hs-conid'>DEFAULT</span>      <span class='hs-keyword'>_</span>           <span class='hs-keyglyph'>=</span> <span class='hs-conid'>LT</span>
<a name="line-24"></a>
<a name="line-25"></a><span class='hs-definition'>cmpAltCon</span> <span class='hs-layout'>(</span><span class='hs-conid'>DataAlt</span> <span class='hs-varid'>d1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>DataAlt</span> <span class='hs-varid'>d2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>dataConTag</span> <span class='hs-varid'>d1</span> <span class='hs-varop'>`compare`</span> <span class='hs-varid'>dataConTag</span> <span class='hs-varid'>d2</span>
<a name="line-26"></a><span class='hs-definition'>cmpAltCon</span> <span class='hs-layout'>(</span><span class='hs-conid'>DataAlt</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>  <span class='hs-conid'>DEFAULT</span>      <span class='hs-keyglyph'>=</span> <span class='hs-conid'>GT</span>
<a name="line-27"></a><span class='hs-definition'>cmpAltCon</span> <span class='hs-layout'>(</span><span class='hs-conid'>LitAlt</span>  <span class='hs-varid'>l1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>LitAlt</span>  <span class='hs-varid'>l2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>l1</span> <span class='hs-varop'>`compare`</span> <span class='hs-varid'>l2</span>
<a name="line-28"></a><span class='hs-definition'>cmpAltCon</span> <span class='hs-layout'>(</span><span class='hs-conid'>LitAlt</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>   <span class='hs-conid'>DEFAULT</span>      <span class='hs-keyglyph'>=</span> <span class='hs-conid'>GT</span>
<a name="line-29"></a>
<a name="line-30"></a><span class='hs-definition'>cmpAltCon</span> <span class='hs-varid'>con1</span> <span class='hs-varid'>con2</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>WARN</span><span class='hs-layout'>(</span> <span class='hs-conid'>True</span><span class='hs-layout'>,</span> <span class='hs-varid'>text</span> <span class='hs-str'>"Comparing incomparable AltCons"</span> <span class='hs-varop'>&lt;+&gt;</span> 
<a name="line-31"></a>			 	  <span class='hs-varid'>ppr</span> <span class='hs-varid'>con1</span> <span class='hs-varop'>&lt;+&gt;</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>con2</span> <span class='hs-layout'>)</span>
<a name="line-32"></a>		      <span class='hs-conid'>LT</span>
</pre>\end{code}

%************************************************************************
%*									*
\subsection{Useful synonyms}
%*									*
%************************************************************************

\begin{code}
<pre><a name="line-1"></a><a name="CoreBndr"></a><span class='hs-comment'>-- | The common case for the type of binders and variables when</span>
<a name="line-2"></a><a name="CoreBndr"></a><span class='hs-comment'>-- we are manipulating the Core language within GHC</span>
<a name="line-3"></a><a name="CoreBndr"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>CoreBndr</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Var</span>
<a name="line-4"></a><a name="CoreExpr"></a><span class='hs-comment'>-- | Expressions where binders are 'CoreBndr's</span>
<a name="line-5"></a><a name="CoreExpr"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>CoreExpr</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Expr</span> <span class='hs-conid'>CoreBndr</span>
<a name="line-6"></a><a name="CoreArg"></a><span class='hs-comment'>-- | Argument expressions where binders are 'CoreBndr's</span>
<a name="line-7"></a><a name="CoreArg"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>CoreArg</span>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Arg</span>  <span class='hs-conid'>CoreBndr</span>
<a name="line-8"></a><a name="CoreBind"></a><span class='hs-comment'>-- | Binding groups where binders are 'CoreBndr's</span>
<a name="line-9"></a><a name="CoreBind"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>CoreBind</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Bind</span> <span class='hs-conid'>CoreBndr</span>
<a name="line-10"></a><a name="CoreAlt"></a><span class='hs-comment'>-- | Case alternatives where binders are 'CoreBndr's</span>
<a name="line-11"></a><a name="CoreAlt"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>CoreAlt</span>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Alt</span>  <span class='hs-conid'>CoreBndr</span>
</pre>\end{code}

%************************************************************************
%*									*
\subsection{Tagging}
%*									*
%************************************************************************

\begin{code}
<pre><a name="line-1"></a><a name="TaggedBndr"></a><span class='hs-comment'>-- | Binders are /tagged/ with a t</span>
<a name="line-2"></a><a name="TaggedBndr"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>TaggedBndr</span> <span class='hs-varid'>t</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>TB</span> <span class='hs-conid'>CoreBndr</span> <span class='hs-varid'>t</span>	<span class='hs-comment'>-- TB for "tagged binder"</span>
<a name="line-3"></a>
<a name="line-4"></a><a name="TaggedBind"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>TaggedBind</span> <span class='hs-varid'>t</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Bind</span> <span class='hs-layout'>(</span><span class='hs-conid'>TaggedBndr</span> <span class='hs-varid'>t</span><span class='hs-layout'>)</span>
<a name="line-5"></a><a name="TaggedExpr"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>TaggedExpr</span> <span class='hs-varid'>t</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Expr</span> <span class='hs-layout'>(</span><span class='hs-conid'>TaggedBndr</span> <span class='hs-varid'>t</span><span class='hs-layout'>)</span>
<a name="line-6"></a><a name="TaggedArg"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>TaggedArg</span>  <span class='hs-varid'>t</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Arg</span>  <span class='hs-layout'>(</span><span class='hs-conid'>TaggedBndr</span> <span class='hs-varid'>t</span><span class='hs-layout'>)</span>
<a name="line-7"></a><a name="TaggedAlt"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>TaggedAlt</span>  <span class='hs-varid'>t</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Alt</span>  <span class='hs-layout'>(</span><span class='hs-conid'>TaggedBndr</span> <span class='hs-varid'>t</span><span class='hs-layout'>)</span>
<a name="line-8"></a>
<a name="line-9"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Outputable</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>Outputable</span> <span class='hs-layout'>(</span><span class='hs-conid'>TaggedBndr</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
<a name="line-10"></a>  <span class='hs-varid'>ppr</span> <span class='hs-layout'>(</span><span class='hs-conid'>TB</span> <span class='hs-varid'>b</span> <span class='hs-varid'>l</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'&lt;'</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>b</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>comma</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>l</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'&gt;'</span>
<a name="line-11"></a>
<a name="line-12"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Outputable</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>OutputableBndr</span> <span class='hs-layout'>(</span><span class='hs-conid'>TaggedBndr</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
<a name="line-13"></a>  <span class='hs-varid'>pprBndr</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>b</span>	<span class='hs-comment'>-- Simple</span>
</pre>\end{code}


%************************************************************************
%*									*
\subsection{Core-constructing functions with checking}
%*									*
%************************************************************************

\begin{code}
<pre><a name="line-1"></a><a name="mkApps"></a><span class='hs-comment'>-- | Apply a list of argument expressions to a function expression in a nested fashion. Prefer to</span>
<a name="line-2"></a><span class='hs-comment'>-- use 'CoreUtils.mkCoreApps' if possible</span>
<a name="line-3"></a><span class='hs-definition'>mkApps</span>    <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Arg</span> <span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-4"></a><a name="mkTyApps"></a><span class='hs-comment'>-- | Apply a list of type argument expressions to a function expression in a nested fashion</span>
<a name="line-5"></a><span class='hs-definition'>mkTyApps</span>  <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Type</span><span class='hs-keyglyph'>]</span>   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-6"></a><a name="mkVarApps"></a><span class='hs-comment'>-- | Apply a list of type or value variables to a function expression in a nested fashion</span>
<a name="line-7"></a><span class='hs-definition'>mkVarApps</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Var</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-8"></a><a name="mkConApp"></a><span class='hs-comment'>-- | Apply a list of argument expressions to a data constructor in a nested fashion. Prefer to</span>
<a name="line-9"></a><span class='hs-comment'>-- use 'MkCore.mkCoreConApps' if possible</span>
<a name="line-10"></a><span class='hs-definition'>mkConApp</span>      <span class='hs-keyglyph'>::</span> <span class='hs-conid'>DataCon</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Arg</span> <span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-11"></a>
<a name="line-12"></a><span class='hs-definition'>mkApps</span>    <span class='hs-varid'>f</span> <span class='hs-varid'>args</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldl</span> <span class='hs-conid'>App</span>		  	   <span class='hs-varid'>f</span> <span class='hs-varid'>args</span>
<a name="line-13"></a><span class='hs-definition'>mkTyApps</span>  <span class='hs-varid'>f</span> <span class='hs-varid'>args</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldl</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span> <span class='hs-varid'>e</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>App</span> <span class='hs-varid'>e</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>f</span> <span class='hs-varid'>args</span>
<a name="line-14"></a><span class='hs-definition'>mkVarApps</span> <span class='hs-varid'>f</span> <span class='hs-varid'>vars</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldl</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span> <span class='hs-varid'>e</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>App</span> <span class='hs-varid'>e</span> <span class='hs-layout'>(</span><span class='hs-varid'>varToCoreExpr</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>f</span> <span class='hs-varid'>vars</span>
<a name="line-15"></a><span class='hs-definition'>mkConApp</span> <span class='hs-varid'>con</span> <span class='hs-varid'>args</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkApps</span> <span class='hs-layout'>(</span><span class='hs-conid'>Var</span> <span class='hs-layout'>(</span><span class='hs-varid'>dataConWorkId</span> <span class='hs-varid'>con</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>args</span>
<a name="line-16"></a>
<a name="line-17"></a>
<a name="line-18"></a><a name="mkIntLit"></a><span class='hs-comment'>-- | Create a machine integer literal expression of type @Int#@ from an @Integer@.</span>
<a name="line-19"></a><span class='hs-comment'>-- If you want an expression of type @Int@ use 'MkCore.mkIntExpr'</span>
<a name="line-20"></a><span class='hs-definition'>mkIntLit</span>      <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Integer</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-21"></a><a name="mkIntLitInt"></a><span class='hs-comment'>-- | Create a machine integer literal expression of type @Int#@ from an @Int@.</span>
<a name="line-22"></a><span class='hs-comment'>-- If you want an expression of type @Int@ use 'MkCore.mkIntExpr'</span>
<a name="line-23"></a><span class='hs-definition'>mkIntLitInt</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-24"></a>
<a name="line-25"></a><span class='hs-definition'>mkIntLit</span>    <span class='hs-varid'>n</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Lit</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkMachInt</span> <span class='hs-varid'>n</span><span class='hs-layout'>)</span>
<a name="line-26"></a><span class='hs-definition'>mkIntLitInt</span> <span class='hs-varid'>n</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Lit</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkMachInt</span> <span class='hs-layout'>(</span><span class='hs-varid'>toInteger</span> <span class='hs-varid'>n</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-27"></a>
<a name="line-28"></a><a name="mkWordLit"></a><span class='hs-comment'>-- | Create a machine word literal expression of type  @Word#@ from an @Integer@.</span>
<a name="line-29"></a><span class='hs-comment'>-- If you want an expression of type @Word@ use 'MkCore.mkWordExpr'</span>
<a name="line-30"></a><span class='hs-definition'>mkWordLit</span>     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Integer</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-31"></a><a name="mkWordLitWord"></a><span class='hs-comment'>-- | Create a machine word literal expression of type  @Word#@ from a @Word@.</span>
<a name="line-32"></a><span class='hs-comment'>-- If you want an expression of type @Word@ use 'MkCore.mkWordExpr'</span>
<a name="line-33"></a><span class='hs-definition'>mkWordLitWord</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Word</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-34"></a>
<a name="line-35"></a><span class='hs-definition'>mkWordLit</span>     <span class='hs-varid'>w</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Lit</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkMachWord</span> <span class='hs-varid'>w</span><span class='hs-layout'>)</span>
<a name="line-36"></a><span class='hs-definition'>mkWordLitWord</span> <span class='hs-varid'>w</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Lit</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkMachWord</span> <span class='hs-layout'>(</span><span class='hs-varid'>toInteger</span> <span class='hs-varid'>w</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-37"></a>
<a name="line-38"></a><a name="mkCharLit"></a><span class='hs-comment'>-- | Create a machine character literal expression of type @Char#@.</span>
<a name="line-39"></a><span class='hs-comment'>-- If you want an expression of type @Char@ use 'MkCore.mkCharExpr'</span>
<a name="line-40"></a><span class='hs-definition'>mkCharLit</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Char</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-41"></a><a name="mkStringLit"></a><span class='hs-comment'>-- | Create a machine string literal expression of type @Addr#@.</span>
<a name="line-42"></a><span class='hs-comment'>-- If you want an expression of type @String@ use 'MkCore.mkStringExpr'</span>
<a name="line-43"></a><span class='hs-definition'>mkStringLit</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-44"></a>
<a name="line-45"></a><span class='hs-definition'>mkCharLit</span>   <span class='hs-varid'>c</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Lit</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkMachChar</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span>
<a name="line-46"></a><span class='hs-definition'>mkStringLit</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Lit</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkMachString</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>
<a name="line-47"></a>
<a name="line-48"></a><a name="mkFloatLit"></a><span class='hs-comment'>-- | Create a machine single precision literal expression of type @Float#@ from a @Rational@.</span>
<a name="line-49"></a><span class='hs-comment'>-- If you want an expression of type @Float@ use 'MkCore.mkFloatExpr'</span>
<a name="line-50"></a><span class='hs-definition'>mkFloatLit</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Rational</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-51"></a><a name="mkFloatLitFloat"></a><span class='hs-comment'>-- | Create a machine single precision literal expression of type @Float#@ from a @Float@.</span>
<a name="line-52"></a><span class='hs-comment'>-- If you want an expression of type @Float@ use 'MkCore.mkFloatExpr'</span>
<a name="line-53"></a><span class='hs-definition'>mkFloatLitFloat</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Float</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-54"></a>
<a name="line-55"></a><span class='hs-definition'>mkFloatLit</span>      <span class='hs-varid'>f</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Lit</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkMachFloat</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span>
<a name="line-56"></a><span class='hs-definition'>mkFloatLitFloat</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Lit</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkMachFloat</span> <span class='hs-layout'>(</span><span class='hs-varid'>toRational</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-57"></a>
<a name="line-58"></a><a name="mkDoubleLit"></a><span class='hs-comment'>-- | Create a machine double precision literal expression of type @Double#@ from a @Rational@.</span>
<a name="line-59"></a><span class='hs-comment'>-- If you want an expression of type @Double@ use 'MkCore.mkDoubleExpr'</span>
<a name="line-60"></a><span class='hs-definition'>mkDoubleLit</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Rational</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-61"></a><a name="mkDoubleLitDouble"></a><span class='hs-comment'>-- | Create a machine double precision literal expression of type @Double#@ from a @Double@.</span>
<a name="line-62"></a><span class='hs-comment'>-- If you want an expression of type @Double@ use 'MkCore.mkDoubleExpr'</span>
<a name="line-63"></a><span class='hs-definition'>mkDoubleLitDouble</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Double</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-64"></a>
<a name="line-65"></a><span class='hs-definition'>mkDoubleLit</span>       <span class='hs-varid'>d</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Lit</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkMachDouble</span> <span class='hs-varid'>d</span><span class='hs-layout'>)</span>
<a name="line-66"></a><span class='hs-definition'>mkDoubleLitDouble</span> <span class='hs-varid'>d</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Lit</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkMachDouble</span> <span class='hs-layout'>(</span><span class='hs-varid'>toRational</span> <span class='hs-varid'>d</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-67"></a>
<a name="line-68"></a><a name="mkLets"></a><span class='hs-comment'>-- | Bind all supplied binding groups over an expression in a nested let expression. Prefer to</span>
<a name="line-69"></a><span class='hs-comment'>-- use 'CoreUtils.mkCoreLets' if possible</span>
<a name="line-70"></a><span class='hs-definition'>mkLets</span>	      <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Bind</span> <span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-71"></a><a name="mkLams"></a><span class='hs-comment'>-- | Bind all supplied binders over an expression in a nested lambda expression. Prefer to</span>
<a name="line-72"></a><span class='hs-comment'>-- use 'CoreUtils.mkCoreLams' if possible</span>
<a name="line-73"></a><span class='hs-definition'>mkLams</span>	      <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-74"></a>
<a name="line-75"></a><span class='hs-definition'>mkLams</span> <span class='hs-varid'>binders</span> <span class='hs-varid'>body</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr</span> <span class='hs-conid'>Lam</span> <span class='hs-varid'>body</span> <span class='hs-varid'>binders</span>
<a name="line-76"></a><span class='hs-definition'>mkLets</span> <span class='hs-varid'>binds</span> <span class='hs-varid'>body</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr</span> <span class='hs-conid'>Let</span> <span class='hs-varid'>body</span> <span class='hs-varid'>binds</span>
<a name="line-77"></a>
<a name="line-78"></a>
<a name="line-79"></a><a name="mkTyBind"></a><span class='hs-comment'>-- | Create a binding group where a type variable is bound to a type. Per "CoreSyn#type_let",</span>
<a name="line-80"></a><span class='hs-comment'>-- this can only be used to bind something in a non-recursive @let@ expression</span>
<a name="line-81"></a><span class='hs-definition'>mkTyBind</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>TyVar</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CoreBind</span>
<a name="line-82"></a><span class='hs-definition'>mkTyBind</span> <span class='hs-varid'>tv</span> <span class='hs-varid'>ty</span>      <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NonRec</span> <span class='hs-varid'>tv</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span>
<a name="line-83"></a>
<a name="line-84"></a><a name="varToCoreExpr"></a><span class='hs-comment'>-- | Convert a binder into either a 'Var' or 'Type' 'Expr' appropriately</span>
<a name="line-85"></a><span class='hs-definition'>varToCoreExpr</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreBndr</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span>
<a name="line-86"></a><span class='hs-definition'>varToCoreExpr</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>isId</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Var</span> <span class='hs-varid'>v</span>
<a name="line-87"></a>                <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Type</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkTyVarTy</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span>
<a name="line-88"></a>
<a name="line-89"></a><a name="varsToCoreExprs"></a><span class='hs-definition'>varsToCoreExprs</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreBndr</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span>
<a name="line-90"></a><span class='hs-definition'>varsToCoreExprs</span> <span class='hs-varid'>vs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>map</span> <span class='hs-varid'>varToCoreExpr</span> <span class='hs-varid'>vs</span>
</pre>\end{code}


%************************************************************************
%*									*
\subsection{Simple access functions}
%*									*
%************************************************************************

\begin{code}
<pre><a name="line-1"></a><a name="bindersOf"></a><span class='hs-comment'>-- | Extract every variable by this group</span>
<a name="line-2"></a><span class='hs-definition'>bindersOf</span>  <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bind</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span>
<a name="line-3"></a><span class='hs-definition'>bindersOf</span> <span class='hs-layout'>(</span><span class='hs-conid'>NonRec</span> <span class='hs-varid'>binder</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>binder</span><span class='hs-keyglyph'>]</span>
<a name="line-4"></a><span class='hs-definition'>bindersOf</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rec</span> <span class='hs-varid'>pairs</span><span class='hs-layout'>)</span>       <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>binder</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>binder</span><span class='hs-layout'>,</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>pairs</span><span class='hs-keyglyph'>]</span>
<a name="line-5"></a>
<a name="line-6"></a><a name="bindersOfBinds"></a><span class='hs-comment'>-- | 'bindersOf' applied to a list of binding groups</span>
<a name="line-7"></a><span class='hs-definition'>bindersOfBinds</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Bind</span> <span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span>
<a name="line-8"></a><span class='hs-definition'>bindersOfBinds</span> <span class='hs-varid'>binds</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varop'>++</span><span class='hs-layout'>)</span> <span class='hs-varop'>.</span> <span class='hs-varid'>bindersOf</span><span class='hs-layout'>)</span> <span class='hs-conid'>[]</span> <span class='hs-varid'>binds</span>
<a name="line-9"></a>
<a name="line-10"></a><a name="rhssOfBind"></a><span class='hs-definition'>rhssOfBind</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bind</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span>
<a name="line-11"></a><span class='hs-definition'>rhssOfBind</span> <span class='hs-layout'>(</span><span class='hs-conid'>NonRec</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>rhs</span><span class='hs-keyglyph'>]</span>
<a name="line-12"></a><span class='hs-definition'>rhssOfBind</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rec</span> <span class='hs-varid'>pairs</span><span class='hs-layout'>)</span>    <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>rhs</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-keyword'>_</span><span class='hs-layout'>,</span><span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>pairs</span><span class='hs-keyglyph'>]</span>
<a name="line-13"></a>
<a name="line-14"></a><a name="rhssOfAlts"></a><span class='hs-definition'>rhssOfAlts</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Alt</span> <span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span>
<a name="line-15"></a><span class='hs-definition'>rhssOfAlts</span> <span class='hs-varid'>alts</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>e</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-keyword'>_</span><span class='hs-layout'>,</span><span class='hs-keyword'>_</span><span class='hs-layout'>,</span><span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>alts</span><span class='hs-keyglyph'>]</span>
<a name="line-16"></a>
<a name="line-17"></a><a name="flattenBinds"></a><span class='hs-comment'>-- | Collapse all the bindings in the supplied groups into a single</span>
<a name="line-18"></a><span class='hs-comment'>-- list of lhs\/rhs pairs suitable for binding in a 'Rec' binding group</span>
<a name="line-19"></a><span class='hs-definition'>flattenBinds</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Bind</span> <span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-layout'>,</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span>
<a name="line-20"></a><span class='hs-definition'>flattenBinds</span> <span class='hs-layout'>(</span><span class='hs-conid'>NonRec</span> <span class='hs-varid'>b</span> <span class='hs-varid'>r</span> <span class='hs-conop'>:</span> <span class='hs-varid'>binds</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-layout'>,</span><span class='hs-varid'>r</span><span class='hs-layout'>)</span> <span class='hs-conop'>:</span> <span class='hs-varid'>flattenBinds</span> <span class='hs-varid'>binds</span>
<a name="line-21"></a><span class='hs-definition'>flattenBinds</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rec</span> <span class='hs-varid'>prs1</span>   <span class='hs-conop'>:</span> <span class='hs-varid'>binds</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>prs1</span> <span class='hs-varop'>++</span> <span class='hs-varid'>flattenBinds</span> <span class='hs-varid'>binds</span>
<a name="line-22"></a><span class='hs-definition'>flattenBinds</span> <span class='hs-conid'>[]</span>			  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>[]</span>
</pre>\end{code}

\begin{code}
<pre><a name="line-1"></a><a name="collectBinders"></a><span class='hs-comment'>-- | We often want to strip off leading lambdas before getting down to</span>
<a name="line-2"></a><span class='hs-comment'>-- business. This function is your friend.</span>
<a name="line-3"></a><span class='hs-definition'>collectBinders</span>	             <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span>         <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span>
<a name="line-4"></a><a name="collectTyBinders"></a><span class='hs-comment'>-- | Collect as many type bindings as possible from the front of a nested lambda</span>
<a name="line-5"></a><span class='hs-definition'>collectTyBinders</span>       	     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreExpr</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>[</span><span class='hs-conid'>TyVar</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span>     <span class='hs-conid'>CoreExpr</span><span class='hs-layout'>)</span>
<a name="line-6"></a><a name="collectValBinders"></a><span class='hs-comment'>-- | Collect as many value bindings as possible from the front of a nested lambda</span>
<a name="line-7"></a><span class='hs-definition'>collectValBinders</span>      	     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreExpr</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>[</span><span class='hs-conid'>Id</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span>        <span class='hs-conid'>CoreExpr</span><span class='hs-layout'>)</span>
<a name="line-8"></a><a name="collectTyAndValBinders"></a><span class='hs-comment'>-- | Collect type binders from the front of the lambda first, </span>
<a name="line-9"></a><span class='hs-comment'>-- then follow up by collecting as many value bindings as possible</span>
<a name="line-10"></a><span class='hs-comment'>-- from the resulting stripped expression</span>
<a name="line-11"></a><span class='hs-definition'>collectTyAndValBinders</span> 	     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreExpr</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>[</span><span class='hs-conid'>TyVar</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Id</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span> <span class='hs-conid'>CoreExpr</span><span class='hs-layout'>)</span>
<a name="line-12"></a>
<a name="line-13"></a><span class='hs-definition'>collectBinders</span> <span class='hs-varid'>expr</span>
<a name="line-14"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-conid'>[]</span> <span class='hs-varid'>expr</span>
<a name="line-15"></a>  <span class='hs-keyword'>where</span>
<a name="line-16"></a>    <span class='hs-varid'>go</span> <span class='hs-varid'>bs</span> <span class='hs-layout'>(</span><span class='hs-conid'>Lam</span> <span class='hs-varid'>b</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-conop'>:</span><span class='hs-varid'>bs</span><span class='hs-layout'>)</span> <span class='hs-varid'>e</span>
<a name="line-17"></a>    <span class='hs-varid'>go</span> <span class='hs-varid'>bs</span> <span class='hs-varid'>e</span>	     <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>reverse</span> <span class='hs-varid'>bs</span><span class='hs-layout'>,</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span>
<a name="line-18"></a>
<a name="line-19"></a><span class='hs-definition'>collectTyAndValBinders</span> <span class='hs-varid'>expr</span>
<a name="line-20"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>tvs</span><span class='hs-layout'>,</span> <span class='hs-varid'>ids</span><span class='hs-layout'>,</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span>
<a name="line-21"></a>  <span class='hs-keyword'>where</span>
<a name="line-22"></a>    <span class='hs-layout'>(</span><span class='hs-varid'>tvs</span><span class='hs-layout'>,</span> <span class='hs-varid'>body1</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>collectTyBinders</span> <span class='hs-varid'>expr</span>
<a name="line-23"></a>    <span class='hs-layout'>(</span><span class='hs-varid'>ids</span><span class='hs-layout'>,</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>collectValBinders</span> <span class='hs-varid'>body1</span>
<a name="line-24"></a>
<a name="line-25"></a><span class='hs-definition'>collectTyBinders</span> <span class='hs-varid'>expr</span>
<a name="line-26"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-conid'>[]</span> <span class='hs-varid'>expr</span>
<a name="line-27"></a>  <span class='hs-keyword'>where</span>
<a name="line-28"></a>    <span class='hs-varid'>go</span> <span class='hs-varid'>tvs</span> <span class='hs-layout'>(</span><span class='hs-conid'>Lam</span> <span class='hs-varid'>b</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>isTyVar</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-conop'>:</span><span class='hs-varid'>tvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>e</span>
<a name="line-29"></a>    <span class='hs-varid'>go</span> <span class='hs-varid'>tvs</span> <span class='hs-varid'>e</span>			 <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>reverse</span> <span class='hs-varid'>tvs</span><span class='hs-layout'>,</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span>
<a name="line-30"></a>
<a name="line-31"></a><span class='hs-definition'>collectValBinders</span> <span class='hs-varid'>expr</span>
<a name="line-32"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-conid'>[]</span> <span class='hs-varid'>expr</span>
<a name="line-33"></a>  <span class='hs-keyword'>where</span>
<a name="line-34"></a>    <span class='hs-varid'>go</span> <span class='hs-varid'>ids</span> <span class='hs-layout'>(</span><span class='hs-conid'>Lam</span> <span class='hs-varid'>b</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>isId</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-conop'>:</span><span class='hs-varid'>ids</span><span class='hs-layout'>)</span> <span class='hs-varid'>e</span>
<a name="line-35"></a>    <span class='hs-varid'>go</span> <span class='hs-varid'>ids</span> <span class='hs-varid'>body</span>		      <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>reverse</span> <span class='hs-varid'>ids</span><span class='hs-layout'>,</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span>
</pre>\end{code}

\begin{code}
<pre><a name="line-1"></a><a name="collectArgs"></a><span class='hs-comment'>-- | Takes a nested application expression and returns the the function</span>
<a name="line-2"></a><span class='hs-comment'>-- being applied and the arguments to which it is applied</span>
<a name="line-3"></a><span class='hs-definition'>collectArgs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Arg</span> <span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-4"></a><span class='hs-definition'>collectArgs</span> <span class='hs-varid'>expr</span>
<a name="line-5"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>expr</span> <span class='hs-conid'>[]</span>
<a name="line-6"></a>  <span class='hs-keyword'>where</span>
<a name="line-7"></a>    <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-conid'>App</span> <span class='hs-varid'>f</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyword'>as</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>f</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-conop'>:</span><span class='hs-keyword'>as</span><span class='hs-layout'>)</span>
<a name="line-8"></a>    <span class='hs-varid'>go</span> <span class='hs-varid'>e</span> 	 <span class='hs-keyword'>as</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>e</span><span class='hs-layout'>,</span> <span class='hs-keyword'>as</span><span class='hs-layout'>)</span>
</pre>\end{code}

\begin{code}
<pre><a name="line-1"></a><a name="coreExprCc"></a><span class='hs-comment'>-- | Gets the cost centre enclosing an expression, if any.</span>
<a name="line-2"></a><span class='hs-comment'>-- It looks inside lambdas because @(scc \"foo\" \\x.e) = \\x. scc \"foo\" e@</span>
<a name="line-3"></a><span class='hs-definition'>coreExprCc</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CostCentre</span>
<a name="line-4"></a><span class='hs-definition'>coreExprCc</span> <span class='hs-layout'>(</span><span class='hs-conid'>Note</span> <span class='hs-layout'>(</span><span class='hs-conid'>SCC</span> <span class='hs-varid'>cc</span><span class='hs-layout'>)</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cc</span>
<a name="line-5"></a><span class='hs-definition'>coreExprCc</span> <span class='hs-layout'>(</span><span class='hs-conid'>Note</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span>          <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coreExprCc</span> <span class='hs-varid'>e</span>
<a name="line-6"></a><span class='hs-definition'>coreExprCc</span> <span class='hs-layout'>(</span><span class='hs-conid'>Lam</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span>           <span class='hs-keyglyph'>=</span> <span class='hs-varid'>coreExprCc</span> <span class='hs-varid'>e</span>
<a name="line-7"></a><span class='hs-definition'>coreExprCc</span> <span class='hs-keyword'>_</span>                   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>noCostCentre</span>
</pre>\end{code}

%************************************************************************
%*									*
\subsection{Predicates}
%*									*
%************************************************************************

At one time we optionally carried type arguments through to runtime.
@isRuntimeVar v@ returns if (Lam v _) really becomes a lambda at runtime,
i.e. if type applications are actual lambdas because types are kept around
at runtime.  Similarly isRuntimeArg.  

\begin{code}
<pre><a name="line-1"></a><a name="isRuntimeVar"></a><span class='hs-comment'>-- | Will this variable exist at runtime?</span>
<a name="line-2"></a><span class='hs-definition'>isRuntimeVar</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Var</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-3"></a><span class='hs-definition'>isRuntimeVar</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>isId</span> 
<a name="line-4"></a>
<a name="line-5"></a><a name="isRuntimeArg"></a><span class='hs-comment'>-- | Will this argument expression exist at runtime?</span>
<a name="line-6"></a><span class='hs-definition'>isRuntimeArg</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreExpr</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-7"></a><span class='hs-definition'>isRuntimeArg</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>isValArg</span>
<a name="line-8"></a>
<a name="line-9"></a><a name="isValArg"></a><span class='hs-comment'>-- | Returns @False@ iff the expression is a 'Type' expression at its top level</span>
<a name="line-10"></a><span class='hs-definition'>isValArg</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-11"></a><span class='hs-definition'>isValArg</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-12"></a><span class='hs-definition'>isValArg</span> <span class='hs-keyword'>_</span>        <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-13"></a>
<a name="line-14"></a><a name="isTypeArg"></a><span class='hs-comment'>-- | Returns @True@ iff the expression is a 'Type' expression at its top level</span>
<a name="line-15"></a><span class='hs-definition'>isTypeArg</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-16"></a><span class='hs-definition'>isTypeArg</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-17"></a><span class='hs-definition'>isTypeArg</span> <span class='hs-keyword'>_</span>        <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-18"></a>
<a name="line-19"></a><a name="valBndrCount"></a><span class='hs-comment'>-- | The number of binders that bind values rather than types</span>
<a name="line-20"></a><span class='hs-definition'>valBndrCount</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreBndr</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
<a name="line-21"></a><span class='hs-definition'>valBndrCount</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>count</span> <span class='hs-varid'>isId</span>
<a name="line-22"></a>
<a name="line-23"></a><a name="valArgCount"></a><span class='hs-comment'>-- | The number of argument expressions that are values rather than types at their top level</span>
<a name="line-24"></a><span class='hs-definition'>valArgCount</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Arg</span> <span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
<a name="line-25"></a><span class='hs-definition'>valArgCount</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>count</span> <span class='hs-varid'>isValArg</span>
</pre>\end{code}


%************************************************************************
%*									*
\subsection{Seq stuff}
%*									*
%************************************************************************

\begin{code}
<pre><a name="line-1"></a><a name="seqExpr"></a><span class='hs-definition'>seqExpr</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreExpr</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>()</span>
<a name="line-2"></a><span class='hs-definition'>seqExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>Var</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span>         <span class='hs-keyglyph'>=</span> <span class='hs-varid'>v</span> <span class='hs-varop'>`seq`</span> <span class='hs-conid'>()</span>
<a name="line-3"></a><span class='hs-definition'>seqExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>Lit</span> <span class='hs-varid'>lit</span><span class='hs-layout'>)</span>       <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lit</span> <span class='hs-varop'>`seq`</span> <span class='hs-conid'>()</span>
<a name="line-4"></a><span class='hs-definition'>seqExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>App</span> <span class='hs-varid'>f</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>       <span class='hs-keyglyph'>=</span> <span class='hs-varid'>seqExpr</span> <span class='hs-varid'>f</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqExpr</span> <span class='hs-varid'>a</span>
<a name="line-5"></a><span class='hs-definition'>seqExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>Lam</span> <span class='hs-varid'>b</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span>       <span class='hs-keyglyph'>=</span> <span class='hs-varid'>seqBndr</span> <span class='hs-varid'>b</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqExpr</span> <span class='hs-varid'>e</span>
<a name="line-6"></a><span class='hs-definition'>seqExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>Let</span> <span class='hs-varid'>b</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span>       <span class='hs-keyglyph'>=</span> <span class='hs-varid'>seqBind</span> <span class='hs-varid'>b</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqExpr</span> <span class='hs-varid'>e</span>
<a name="line-7"></a><span class='hs-definition'>seqExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>Case</span> <span class='hs-varid'>e</span> <span class='hs-varid'>b</span> <span class='hs-varid'>t</span> <span class='hs-keyword'>as</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>seqExpr</span> <span class='hs-varid'>e</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqBndr</span> <span class='hs-varid'>b</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqType</span> <span class='hs-varid'>t</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqAlts</span> <span class='hs-keyword'>as</span>
<a name="line-8"></a><span class='hs-definition'>seqExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>Cast</span> <span class='hs-varid'>e</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span>     <span class='hs-keyglyph'>=</span> <span class='hs-varid'>seqExpr</span> <span class='hs-varid'>e</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqType</span> <span class='hs-varid'>co</span>
<a name="line-9"></a><span class='hs-definition'>seqExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>Note</span> <span class='hs-varid'>n</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span>      <span class='hs-keyglyph'>=</span> <span class='hs-varid'>seqNote</span> <span class='hs-varid'>n</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqExpr</span> <span class='hs-varid'>e</span>
<a name="line-10"></a><span class='hs-definition'>seqExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span> <span class='hs-varid'>t</span><span class='hs-layout'>)</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>seqType</span> <span class='hs-varid'>t</span>
<a name="line-11"></a>
<a name="line-12"></a><a name="seqExprs"></a><span class='hs-definition'>seqExprs</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreExpr</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>()</span>
<a name="line-13"></a><span class='hs-definition'>seqExprs</span> <span class='hs-conid'>[]</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>()</span>
<a name="line-14"></a><span class='hs-definition'>seqExprs</span> <span class='hs-layout'>(</span><span class='hs-varid'>e</span><span class='hs-conop'>:</span><span class='hs-varid'>es</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>seqExpr</span> <span class='hs-varid'>e</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqExprs</span> <span class='hs-varid'>es</span>
<a name="line-15"></a>
<a name="line-16"></a><a name="seqNote"></a><span class='hs-definition'>seqNote</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Note</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>()</span>
<a name="line-17"></a><span class='hs-definition'>seqNote</span> <span class='hs-layout'>(</span><span class='hs-conid'>CoreNote</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s</span> <span class='hs-varop'>`seq`</span> <span class='hs-conid'>()</span>
<a name="line-18"></a><span class='hs-definition'>seqNote</span> <span class='hs-keyword'>_</span>              <span class='hs-keyglyph'>=</span> <span class='hs-conid'>()</span>
<a name="line-19"></a>
<a name="line-20"></a><a name="seqBndr"></a><span class='hs-definition'>seqBndr</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CoreBndr</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>()</span>
<a name="line-21"></a><span class='hs-definition'>seqBndr</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>b</span> <span class='hs-varop'>`seq`</span> <span class='hs-conid'>()</span>
<a name="line-22"></a>
<a name="line-23"></a><a name="seqBndrs"></a><span class='hs-definition'>seqBndrs</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreBndr</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>()</span>
<a name="line-24"></a><span class='hs-definition'>seqBndrs</span> <span class='hs-conid'>[]</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>()</span>
<a name="line-25"></a><span class='hs-definition'>seqBndrs</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-conop'>:</span><span class='hs-varid'>bs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>seqBndr</span> <span class='hs-varid'>b</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqBndrs</span> <span class='hs-varid'>bs</span>
<a name="line-26"></a>
<a name="line-27"></a><a name="seqBind"></a><span class='hs-definition'>seqBind</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bind</span> <span class='hs-conid'>CoreBndr</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>()</span>
<a name="line-28"></a><span class='hs-definition'>seqBind</span> <span class='hs-layout'>(</span><span class='hs-conid'>NonRec</span> <span class='hs-varid'>b</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>seqBndr</span> <span class='hs-varid'>b</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqExpr</span> <span class='hs-varid'>e</span>
<a name="line-29"></a><span class='hs-definition'>seqBind</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rec</span> <span class='hs-varid'>prs</span><span class='hs-layout'>)</span>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>seqPairs</span> <span class='hs-varid'>prs</span>
<a name="line-30"></a>
<a name="line-31"></a><a name="seqPairs"></a><span class='hs-definition'>seqPairs</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-conid'>CoreBndr</span><span class='hs-layout'>,</span> <span class='hs-conid'>CoreExpr</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>()</span>
<a name="line-32"></a><span class='hs-definition'>seqPairs</span> <span class='hs-conid'>[]</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>()</span>
<a name="line-33"></a><span class='hs-definition'>seqPairs</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-layout'>,</span><span class='hs-varid'>e</span><span class='hs-layout'>)</span><span class='hs-conop'>:</span><span class='hs-varid'>prs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>seqBndr</span> <span class='hs-varid'>b</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqExpr</span> <span class='hs-varid'>e</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqPairs</span> <span class='hs-varid'>prs</span>
<a name="line-34"></a>
<a name="line-35"></a><a name="seqAlts"></a><span class='hs-definition'>seqAlts</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreAlt</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>()</span>
<a name="line-36"></a><span class='hs-definition'>seqAlts</span> <span class='hs-conid'>[]</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>()</span>
<a name="line-37"></a><span class='hs-definition'>seqAlts</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>c</span><span class='hs-layout'>,</span><span class='hs-varid'>bs</span><span class='hs-layout'>,</span><span class='hs-varid'>e</span><span class='hs-layout'>)</span><span class='hs-conop'>:</span><span class='hs-varid'>alts</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>c</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqBndrs</span> <span class='hs-varid'>bs</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqExpr</span> <span class='hs-varid'>e</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqAlts</span> <span class='hs-varid'>alts</span>
<a name="line-38"></a>
<a name="line-39"></a><a name="seqRules"></a><span class='hs-definition'>seqRules</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreRule</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>()</span>
<a name="line-40"></a><span class='hs-definition'>seqRules</span> <span class='hs-conid'>[]</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>()</span>
<a name="line-41"></a><span class='hs-definition'>seqRules</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rule</span> <span class='hs-layout'>{</span> <span class='hs-varid'>ru_bndrs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>bndrs</span><span class='hs-layout'>,</span> <span class='hs-varid'>ru_args</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>args</span><span class='hs-layout'>,</span> <span class='hs-varid'>ru_rhs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>rhs</span> <span class='hs-layout'>}</span> <span class='hs-conop'>:</span> <span class='hs-varid'>rules</span><span class='hs-layout'>)</span> 
<a name="line-42"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>seqBndrs</span> <span class='hs-varid'>bndrs</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqExprs</span> <span class='hs-layout'>(</span><span class='hs-varid'>rhs</span><span class='hs-conop'>:</span><span class='hs-varid'>args</span><span class='hs-layout'>)</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>seqRules</span> <span class='hs-varid'>rules</span>
<a name="line-43"></a><span class='hs-definition'>seqRules</span> <span class='hs-layout'>(</span><span class='hs-conid'>BuiltinRule</span> <span class='hs-layout'>{</span><span class='hs-layout'>}</span> <span class='hs-conop'>:</span> <span class='hs-varid'>rules</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>seqRules</span> <span class='hs-varid'>rules</span>
</pre>\end{code}

%************************************************************************
%*									*
\subsection{Annotated core}
%*									*
%************************************************************************

\begin{code}
<pre><a name="line-1"></a><a name="AnnExpr"></a><span class='hs-comment'>-- | Annotated core: allows annotation at every node in the tree</span>
<a name="line-2"></a><a name="AnnExpr"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>AnnExpr</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>annot</span><span class='hs-layout'>,</span> <span class='hs-conid'>AnnExpr'</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span><span class='hs-layout'>)</span>
<a name="line-3"></a>
<a name="line-4"></a><a name="AnnExpr'"></a><span class='hs-comment'>-- | A clone of the 'Expr' type but allowing annotation at every tree node</span>
<a name="line-5"></a><a name="AnnExpr'"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>AnnExpr'</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span>
<a name="line-6"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AnnVar</span>	<span class='hs-conid'>Id</span>
<a name="line-7"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>AnnLit</span>	<span class='hs-conid'>Literal</span>
<a name="line-8"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>AnnLam</span>	<span class='hs-varid'>bndr</span> <span class='hs-layout'>(</span><span class='hs-conid'>AnnExpr</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span><span class='hs-layout'>)</span>
<a name="line-9"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>AnnApp</span>	<span class='hs-layout'>(</span><span class='hs-conid'>AnnExpr</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>AnnExpr</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span><span class='hs-layout'>)</span>
<a name="line-10"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>AnnCase</span>	<span class='hs-layout'>(</span><span class='hs-conid'>AnnExpr</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span><span class='hs-layout'>)</span> <span class='hs-varid'>bndr</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>AnnAlt</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span><span class='hs-keyglyph'>]</span>
<a name="line-11"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>AnnLet</span>	<span class='hs-layout'>(</span><span class='hs-conid'>AnnBind</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>AnnExpr</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span><span class='hs-layout'>)</span>
<a name="line-12"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>AnnCast</span>     <span class='hs-layout'>(</span><span class='hs-conid'>AnnExpr</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span><span class='hs-layout'>)</span> <span class='hs-conid'>Coercion</span>
<a name="line-13"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>AnnNote</span>	<span class='hs-conid'>Note</span> <span class='hs-layout'>(</span><span class='hs-conid'>AnnExpr</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span><span class='hs-layout'>)</span>
<a name="line-14"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>AnnType</span>	<span class='hs-conid'>Type</span>
<a name="line-15"></a>
<a name="line-16"></a><a name="AnnAlt"></a><span class='hs-comment'>-- | A clone of the 'Alt' type but allowing annotation at every tree node</span>
<a name="line-17"></a><a name="AnnAlt"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>AnnAlt</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>AltCon</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>bndr</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span> <span class='hs-conid'>AnnExpr</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span><span class='hs-layout'>)</span>
<a name="line-18"></a>
<a name="line-19"></a><a name="AnnBind"></a><span class='hs-comment'>-- | A clone of the 'Bind' type but allowing annotation at every tree node</span>
<a name="line-20"></a><a name="AnnBind"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>AnnBind</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span>
<a name="line-21"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AnnNonRec</span> <span class='hs-varid'>bndr</span> <span class='hs-layout'>(</span><span class='hs-conid'>AnnExpr</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span><span class='hs-layout'>)</span>
<a name="line-22"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>AnnRec</span>    <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-varid'>bndr</span><span class='hs-layout'>,</span> <span class='hs-conid'>AnnExpr</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span>
</pre>\end{code}

\begin{code}
<pre><a name="line-1"></a><a name="deAnnotate"></a><span class='hs-definition'>deAnnotate</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>AnnExpr</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>bndr</span>
<a name="line-2"></a><span class='hs-definition'>deAnnotate</span> <span class='hs-layout'>(</span><span class='hs-keyword'>_</span><span class='hs-layout'>,</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>deAnnotate'</span> <span class='hs-varid'>e</span>
<a name="line-3"></a>
<a name="line-4"></a><a name="deAnnotate'"></a><span class='hs-definition'>deAnnotate'</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>AnnExpr'</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Expr</span> <span class='hs-varid'>bndr</span>
<a name="line-5"></a><span class='hs-definition'>deAnnotate'</span> <span class='hs-layout'>(</span><span class='hs-conid'>AnnType</span> <span class='hs-varid'>t</span><span class='hs-layout'>)</span>           <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Type</span> <span class='hs-varid'>t</span>
<a name="line-6"></a><span class='hs-definition'>deAnnotate'</span> <span class='hs-layout'>(</span><span class='hs-conid'>AnnVar</span>  <span class='hs-varid'>v</span><span class='hs-layout'>)</span>           <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Var</span> <span class='hs-varid'>v</span>
<a name="line-7"></a><span class='hs-definition'>deAnnotate'</span> <span class='hs-layout'>(</span><span class='hs-conid'>AnnLit</span>  <span class='hs-varid'>lit</span><span class='hs-layout'>)</span>         <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Lit</span> <span class='hs-varid'>lit</span>
<a name="line-8"></a><span class='hs-definition'>deAnnotate'</span> <span class='hs-layout'>(</span><span class='hs-conid'>AnnLam</span>  <span class='hs-varid'>binder</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Lam</span> <span class='hs-varid'>binder</span> <span class='hs-layout'>(</span><span class='hs-varid'>deAnnotate</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span>
<a name="line-9"></a><span class='hs-definition'>deAnnotate'</span> <span class='hs-layout'>(</span><span class='hs-conid'>AnnApp</span>  <span class='hs-varid'>fun</span> <span class='hs-varid'>arg</span><span class='hs-layout'>)</span>     <span class='hs-keyglyph'>=</span> <span class='hs-conid'>App</span> <span class='hs-layout'>(</span><span class='hs-varid'>deAnnotate</span> <span class='hs-varid'>fun</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>deAnnotate</span> <span class='hs-varid'>arg</span><span class='hs-layout'>)</span>
<a name="line-10"></a><span class='hs-definition'>deAnnotate'</span> <span class='hs-layout'>(</span><span class='hs-conid'>AnnCast</span> <span class='hs-varid'>e</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span>        <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Cast</span> <span class='hs-layout'>(</span><span class='hs-varid'>deAnnotate</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-varid'>co</span>
<a name="line-11"></a><span class='hs-definition'>deAnnotate'</span> <span class='hs-layout'>(</span><span class='hs-conid'>AnnNote</span> <span class='hs-varid'>note</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span>   <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Note</span> <span class='hs-varid'>note</span> <span class='hs-layout'>(</span><span class='hs-varid'>deAnnotate</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span>
<a name="line-12"></a>
<a name="line-13"></a><span class='hs-definition'>deAnnotate'</span> <span class='hs-layout'>(</span><span class='hs-conid'>AnnLet</span> <span class='hs-varid'>bind</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span>
<a name="line-14"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Let</span> <span class='hs-layout'>(</span><span class='hs-varid'>deAnnBind</span> <span class='hs-varid'>bind</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>deAnnotate</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span>
<a name="line-15"></a>  <span class='hs-keyword'>where</span>
<a name="line-16"></a>    <span class='hs-varid'>deAnnBind</span> <span class='hs-layout'>(</span><span class='hs-conid'>AnnNonRec</span> <span class='hs-varid'>var</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NonRec</span> <span class='hs-varid'>var</span> <span class='hs-layout'>(</span><span class='hs-varid'>deAnnotate</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span>
<a name="line-17"></a>    <span class='hs-varid'>deAnnBind</span> <span class='hs-layout'>(</span><span class='hs-conid'>AnnRec</span> <span class='hs-varid'>pairs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Rec</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-varid'>v</span><span class='hs-layout'>,</span><span class='hs-varid'>deAnnotate</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>v</span><span class='hs-layout'>,</span><span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>pairs</span><span class='hs-keyglyph'>]</span>
<a name="line-18"></a>
<a name="line-19"></a><span class='hs-definition'>deAnnotate'</span> <span class='hs-layout'>(</span><span class='hs-conid'>AnnCase</span> <span class='hs-varid'>scrut</span> <span class='hs-varid'>v</span> <span class='hs-varid'>t</span> <span class='hs-varid'>alts</span><span class='hs-layout'>)</span>
<a name="line-20"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Case</span> <span class='hs-layout'>(</span><span class='hs-varid'>deAnnotate</span> <span class='hs-varid'>scrut</span><span class='hs-layout'>)</span> <span class='hs-varid'>v</span> <span class='hs-varid'>t</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>deAnnAlt</span> <span class='hs-varid'>alts</span><span class='hs-layout'>)</span>
<a name="line-21"></a>
<a name="line-22"></a><a name="deAnnAlt"></a><span class='hs-definition'>deAnnAlt</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>AnnAlt</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Alt</span> <span class='hs-varid'>bndr</span>
<a name="line-23"></a><span class='hs-definition'>deAnnAlt</span> <span class='hs-layout'>(</span><span class='hs-varid'>con</span><span class='hs-layout'>,</span><span class='hs-varid'>args</span><span class='hs-layout'>,</span><span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>con</span><span class='hs-layout'>,</span><span class='hs-varid'>args</span><span class='hs-layout'>,</span><span class='hs-varid'>deAnnotate</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span>
</pre>\end{code}

\begin{code}
<pre><a name="line-1"></a><a name="collectAnnBndrs"></a><span class='hs-comment'>-- | As 'collectBinders' but for 'AnnExpr' rather than 'Expr'</span>
<a name="line-2"></a><span class='hs-definition'>collectAnnBndrs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>AnnExpr</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>bndr</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span> <span class='hs-conid'>AnnExpr</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>annot</span><span class='hs-layout'>)</span>
<a name="line-3"></a><span class='hs-definition'>collectAnnBndrs</span> <span class='hs-varid'>e</span>
<a name="line-4"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>collect</span> <span class='hs-conid'>[]</span> <span class='hs-varid'>e</span>
<a name="line-5"></a>  <span class='hs-keyword'>where</span>
<a name="line-6"></a>    <span class='hs-varid'>collect</span> <span class='hs-varid'>bs</span> <span class='hs-layout'>(</span><span class='hs-keyword'>_</span><span class='hs-layout'>,</span> <span class='hs-conid'>AnnLam</span> <span class='hs-varid'>b</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>collect</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-conop'>:</span><span class='hs-varid'>bs</span><span class='hs-layout'>)</span> <span class='hs-varid'>body</span>
<a name="line-7"></a>    <span class='hs-varid'>collect</span> <span class='hs-varid'>bs</span> <span class='hs-varid'>body</span>		  <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>reverse</span> <span class='hs-varid'>bs</span><span class='hs-layout'>,</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span>
</pre>\end{code}
</body>
</html>