[project @ 2001-02-15 17:33:53 by simonmar]
[ghc-hetmet.git] / ghc / docs / users_guide / glasgow_exts.sgml
index c7d50be..bedbc08 100644 (file)
@@ -2,7 +2,7 @@
 <IndexTerm><Primary>language, GHC</Primary></IndexTerm>
 <IndexTerm><Primary>extensions, GHC</Primary></IndexTerm>
 As with all known Haskell systems, GHC implements some extensions to
-the language.  To use them, you'll need to give a <Literal>-fglasgow-exts</Literal>
+the language.  To use them, you'll need to give a <Option>-fglasgow-exts</Option>
 <IndexTerm><Primary>-fglasgow-exts option</Primary></IndexTerm> option.
 </Para>
 
@@ -10,11 +10,9 @@ the language.  To use them, you'll need to give a <Literal>-fglasgow-exts</Liter
 Virtually all of the Glasgow extensions serve to give you access to
 the underlying facilities with which we implement Haskell.  Thus, you
 can get at the Raw Iron, if you are willing to write some non-standard
-code at a more primitive level.  You need not be ``stuck'' on
+code at a more primitive level.  You need not be &ldquo;stuck&rdquo; on
 performance because of the implementation costs of Haskell's
-``high-level'' features&mdash;you can always code ``under'' them.  In an
-extreme case, you can write all your time-critical code in C, and then
-just glue it together with Haskell!
+&ldquo;high-level&rdquo; features&mdash;you can always code &ldquo;under&rdquo; them.  In an extreme case, you can write all your time-critical code in C, and then just glue it together with Haskell!
 </Para>
 
 <Para>
@@ -29,7 +27,7 @@ Executive summary of our extensions:
 <ListItem>
 <Para>
 You can get right down to the raw machine types and operations;
-included in this are ``primitive arrays'' (direct access to Big Wads
+included in this are &ldquo;primitive arrays&rdquo; (direct access to Big Wads
 of Bytes).  Please see <XRef LinkEnd="glasgow-unboxed"> and following.
 </Para>
 </ListItem>
@@ -78,11 +76,20 @@ for some nested declarations, where this would not be legal in Haskell
 </VarListEntry>
 
 <VarListEntry>
-<Term>Calling out to C:</Term>
+<Term>Pattern guards</Term>
+<ListItem>
+<Para>
+Instead of being a boolean expression, a guard is a list of qualifiers, exactly as in a list comprehension. See <XRef LinkEnd="pattern-guards">.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term>Foreign calling:</Term>
 <ListItem>
 <Para>
 Just what it sounds like.  We provide <Emphasis>lots</Emphasis> of rope that you
-can dangle around your neck.  Please see <XRef LinkEnd="glasgow-ccalls">.
+can dangle around your neck.  Please see <XRef LinkEnd="ffi">.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -107,17 +114,180 @@ Details in <XRef LinkEnd="rewrite-rules">.
 </Para>
 </ListItem>
 </VarListEntry>
+
+<VarListEntry>
+<Term>Generic classes:</Term>
+<ListItem>
+<Para>
+Generic class declarations allow you to define a class
+whose methods say how to work over an arbitrary data type.
+Then it's really easy to make any new type into an instance of
+the class.  This generalises the rather ad-hoc "deriving" feature
+of Haskell 98.
+Details in <XRef LinkEnd="generic-classes">.
+</Para>
+</ListItem>
+</VarListEntry>
 </VariableList>
 </Para>
 
 <Para>
 Before you get too carried away working at the lowest level (e.g.,
-sloshing <Literal>MutableByteArray&num;</Literal>s around your program), you may wish to
-check if there are system libraries that provide a ``Haskellised
-veneer'' over the features you want.  See <XRef LinkEnd="ghc-prelude">.
+sloshing <Literal>MutableByteArray&num;</Literal>s around your
+program), you may wish to check if there are libraries that provide a
+&ldquo;Haskellised veneer&rdquo; over the features you want.  See
+<xref linkend="book-hslibs">.
+</Para>
+
+  <sect1 id="options-language">
+    <title>Language options</title>
+
+    <indexterm><primary>language</primary><secondary>option</secondary>
+    </indexterm>
+    <indexterm><primary>options</primary><secondary>language</secondary>
+    </indexterm>
+    <indexterm><primary>extensions</primary><secondary>options controlling</secondary>
+    </indexterm>
+
+    <para> These flags control what variation of the language are
+    permitted.  Leaving out all of them gives you standard Haskell
+    98.</Para>
+
+    <variablelist>
+
+      <varlistentry>
+       <term><option>-fglasgow-exts</option>:</term>
+       <indexterm><primary><option>-fglasgow-exts</option></primary></indexterm>
+       <listitem>
+         <para>This simultaneously enables all of the extensions to
+          Haskell 98 described in <xref
+          linkend="ghc-language-features">, except where otherwise
+          noted. </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term><option>-fno-monomorphism-restriction</option>:</term>
+       <indexterm><primary><option>-fno-monomorphism-restriction</option></primary></indexterm>
+       <listitem>
+         <para> Switch off the Haskell 98 monomorphism restriction.
+          Independent of the <Option>-fglasgow-exts</Option>
+          flag. </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term><option>-fallow-overlapping-instances</option></term>
+       <term><option>-fallow-undecidable-instances</option></term>
+       <term><option>-fcontext-stack</option></term>
+       <indexterm><primary><option>-fallow-overlapping-instances</option></primary></indexterm>
+       <indexterm><primary><option>-fallow-undecidable-instances</option></primary></indexterm>
+       <indexterm><primary><option>-fcontext-stack</option></primary></indexterm>
+       <listitem>
+         <para> See <XRef LinkEnd="instance-decls">.  Only relevant
+          if you also use <option>-fglasgow-exts</option>.</para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term><option>-fignore-asserts</option>:</term>
+       <indexterm><primary><option>-fignore-asserts</option></primary></indexterm>
+       <listitem>
+         <para>See <XRef LinkEnd="sec-assertions">.  Only relevant if
+          you also use <option>-fglasgow-exts</option>.</Para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term><option>-finline-phase</option></term>
+       <indexterm><primary><option>-finline-phase</option></primary></indexterm>
+       <listitem>
+         <para>See <XRef LinkEnd="rewrite-rules">.  Only relevant if
+          you also use <Option>-fglasgow-exts</Option>.</para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term><option>-fgenerics</option></term>
+       <indexterm><primary><option>-fgenerics</option></primary></indexterm>
+       <listitem>
+         <para>See <XRef LinkEnd="generic-classes">.  Independent of
+          <Option>-fglasgow-exts</Option>.</para>
+       </listitem>
+      </varlistentry>
+
+       <varlistentry>
+         <term><option>-fno-implicit-prelude</option></term>
+         <listitem>
+           <para><indexterm><primary>-fno-implicit-prelude
+            option</primary></indexterm> GHC normally imports
+            <filename>Prelude.hi</filename> files for you.  If you'd
+            rather it didn't, then give it a
+            <option>-fno-implicit-prelude</option> option.  The idea
+            is that you can then import a Prelude of your own.  (But
+            don't call it <literal>Prelude</literal>; the Haskell
+            module namespace is flat, and you must not conflict with
+            any Prelude module.)</para>
+
+           <para>Even though you have not imported the Prelude, all
+            the built-in syntax still refers to the built-in Haskell
+            Prelude types and values, as specified by the Haskell
+            Report.  For example, the type <literal>[Int]</literal>
+            still means <literal>Prelude.[] Int</literal>; tuples
+            continue to refer to the standard Prelude tuples; the
+            translation for list comprehensions continues to use
+            <literal>Prelude.map</literal> etc.</para>
+
+           <para> With one group of exceptions!  You may want to
+            define your own numeric class hierarchy.  It completely
+            defeats that purpose if the literal "1" means
+            "<literal>Prelude.fromInteger 1</literal>", which is what
+            the Haskell Report specifies.  So the
+            <option>-fno-implicit-prelude</option> flag causes the
+            following pieces of built-in syntax to refer to whatever
+            is in scope, not the Prelude versions:</para>
+
+           <itemizedlist>
+             <listitem>
+               <para>Integer and fractional literals mean
+                "<literal>fromInteger 1</literal>" and
+                "<literal>fromRational 3.2</literal>", not the
+                Prelude-qualified versions; both in expressions and in
+                patterns.</para>
+             </listitem>
+
+             <listitem>
+               <para>Negation (e.g. "<literal>- (f x)</literal>")
+               means "<literal>negate (f x)</literal>" (not
+               <literal>Prelude.negate</literal>).</para>
+             </listitem>
+
+             <listitem>
+               <para>In an n+k pattern, the standard Prelude
+                <literal>Ord</literal> class is used for comparison,
+                but the necessary subtraction uses whatever
+                "<literal>(-)</literal>" is in scope (not
+                "<literal>Prelude.(-)</literal>").</para>
+             </listitem>
+           </itemizedlist>
+
+         </listitem>
+       </varlistentry>
+
+    </variablelist>
+  </sect1>
+
+<Sect1 id="primitives">
+<Title>Unboxed types and primitive operations
+</Title>
+<IndexTerm><Primary>PrelGHC module</Primary></IndexTerm>
+
+<Para>
+This module defines all the types which are primitive in Glasgow
+Haskell, and the operations provided for them.
 </Para>
 
-<Sect1 id="glasgow-unboxed">
+<Sect2 id="glasgow-unboxed">
 <Title>Unboxed types
 </Title>
 
@@ -125,1028 +295,1434 @@ veneer'' over the features you want.  See <XRef LinkEnd="ghc-prelude">.
 <IndexTerm><Primary>Unboxed types (Glasgow extension)</Primary></IndexTerm>
 </Para>
 
-<Para>
-These types correspond to the ``raw machine'' types you would use in
-C: <Literal>Int&num;</Literal> (long int), <Literal>Double&num;</Literal> (double), <Literal>Addr&num;</Literal> (void *), etc.  The
-<Emphasis>primitive operations</Emphasis> (PrimOps) on these types are what you
-might expect; e.g., <Literal>(+&num;)</Literal> is addition on <Literal>Int&num;</Literal>s, and is the
-machine-addition that we all know and love&mdash;usually one instruction.
-</Para>
-
-<Para>
-There are some restrictions on the use of unboxed types, the main one
-being that you can't pass an unboxed value to a polymorphic function
-or store one in a polymorphic data type.  This rules out things like
-<Literal>[Int&num;]</Literal> (ie. lists of unboxed integers).  The reason for this
-restriction is that polymorphic arguments and constructor fields are
-assumed to be pointers: if an unboxed integer is stored in one of
-these, the garbage collector would attempt to follow it, leading to
-unpredictable space leaks.  Or a <Literal>seq</Literal> operation on the polymorphic
-component may attempt to dereference the pointer, with disastrous
-results.  Even worse, the unboxed value might be larger than a pointer
+<para>Most types in GHC are <firstterm>boxed</firstterm>, which means
+that values of that type are represented by a pointer to a heap
+object.  The representation of a Haskell <literal>Int</literal>, for
+example, is a two-word heap object.  An <firstterm>unboxed</firstterm>
+type, however, is represented by the value itself, no pointers or heap
+allocation are involved.
+</para>
+
+<Para>
+Unboxed types correspond to the &ldquo;raw machine&rdquo; types you
+would use in C: <Literal>Int&num;</Literal> (long int),
+<Literal>Double&num;</Literal> (double), <Literal>Addr&num;</Literal>
+(void *), etc.  The <Emphasis>primitive operations</Emphasis>
+(PrimOps) on these types are what you might expect; e.g.,
+<Literal>(+&num;)</Literal> is addition on
+<Literal>Int&num;</Literal>s, and is the machine-addition that we all
+know and love&mdash;usually one instruction.
+</Para>
+
+<Para>
+Primitive (unboxed) types cannot be defined in Haskell, and are
+therefore built into the language and compiler.  Primitive types are
+always unlifted; that is, a value of a primitive type cannot be
+bottom.  We use the convention that primitive types, values, and
+operations have a <Literal>&num;</Literal> suffix.
+</Para>
+
+<Para>
+Primitive values are often represented by a simple bit-pattern, such
+as <Literal>Int&num;</Literal>, <Literal>Float&num;</Literal>,
+<Literal>Double&num;</Literal>.  But this is not necessarily the case:
+a primitive value might be represented by a pointer to a
+heap-allocated object.  Examples include
+<Literal>Array&num;</Literal>, the type of primitive arrays.  A
+primitive array is heap-allocated because it is too big a value to fit
+in a register, and would be too expensive to copy around; in a sense,
+it is accidental that it is represented by a pointer.  If a pointer
+represents a primitive value, then it really does point to that value:
+no unevaluated thunks, no indirections&hellip;nothing can be at the
+other end of the pointer than the primitive value.
+</Para>
+
+<Para>
+There are some restrictions on the use of primitive types, the main
+one being that you can't pass a primitive value to a polymorphic
+function or store one in a polymorphic data type.  This rules out
+things like <Literal>[Int&num;]</Literal> (i.e. lists of primitive
+integers).  The reason for this restriction is that polymorphic
+arguments and constructor fields are assumed to be pointers: if an
+unboxed integer is stored in one of these, the garbage collector would
+attempt to follow it, leading to unpredictable space leaks.  Or a
+<Function>seq</Function> operation on the polymorphic component may
+attempt to dereference the pointer, with disastrous results.  Even
+worse, the unboxed value might be larger than a pointer
 (<Literal>Double&num;</Literal> for instance).
 </Para>
 
 <Para>
 Nevertheless, A numerically-intensive program using unboxed types can
-go a <Emphasis>lot</Emphasis> faster than its ``standard'' counterpart&mdash;we saw a
-threefold speedup on one example.
-</Para>
-
-<Para>
-Please see <XRef LinkEnd="ghc-libs-ghc"> for the details of unboxed types and the
-operations on them.
+go a <Emphasis>lot</Emphasis> faster than its &ldquo;standard&rdquo;
+counterpart&mdash;we saw a threefold speedup on one example.
 </Para>
 
-</Sect1>
+</sect2>
 
-<Sect1 id="glasgow-ST-monad">
-<Title>Primitive state-transformer monad
+<Sect2 id="unboxed-tuples">
+<Title>Unboxed Tuples
 </Title>
 
 <Para>
-<IndexTerm><Primary>state transformers (Glasgow extensions)</Primary></IndexTerm>
-<IndexTerm><Primary>ST monad (Glasgow extension)</Primary></IndexTerm>
-</Para>
-
-<Para>
-This monad underlies our implementation of arrays, mutable and
-immutable, and our implementation of I/O, including ``C calls''.
+Unboxed tuples aren't really exported by <Literal>PrelGHC</Literal>,
+they're available by default with <Option>-fglasgow-exts</Option>.  An
+unboxed tuple looks like this:
 </Para>
 
 <Para>
-The <Literal>ST</Literal> library, which provides access to the <Literal>ST</Literal> monad, is a
-GHC/Hugs extension library and is described in the separate <ULink
-URL="libs.html"
->GHC/Hugs Extension Libraries</ULink
-> document.
-</Para>
 
-</Sect1>
+<ProgramListing>
+(# e_1, ..., e_n #)
+</ProgramListing>
 
-<Sect1 id="glasgow-prim-arrays">
-<Title>Primitive arrays, mutable and otherwise
-</Title>
+</Para>
 
 <Para>
-<IndexTerm><Primary>primitive arrays (Glasgow extension)</Primary></IndexTerm>
-<IndexTerm><Primary>arrays, primitive (Glasgow extension)</Primary></IndexTerm>
+where <Literal>e&lowbar;1..e&lowbar;n</Literal> are expressions of any
+type (primitive or non-primitive).  The type of an unboxed tuple looks
+the same.
 </Para>
 
 <Para>
-GHC knows about quite a few flavours of Large Swathes of Bytes.
+Unboxed tuples are used for functions that need to return multiple
+values, but they avoid the heap allocation normally associated with
+using fully-fledged tuples.  When an unboxed tuple is returned, the
+components are put directly into registers or on the stack; the
+unboxed tuple itself does not have a composite representation.  Many
+of the primitive operations listed in this section return unboxed
+tuples.
 </Para>
 
 <Para>
-First, GHC distinguishes between primitive arrays of (boxed) Haskell
-objects (type <Literal>Array&num; obj</Literal>) and primitive arrays of bytes (type
-<Literal>ByteArray&num;</Literal>).
+There are some pretty stringent restrictions on the use of unboxed tuples:
 </Para>
 
 <Para>
-Second, it distinguishes between&hellip;
-<VariableList>
 
-<VarListEntry>
-<Term>Immutable:</Term>
+<ItemizedList>
 <ListItem>
+
 <Para>
-Arrays that do not change (as with ``standard'' Haskell arrays); you
-can only read from them.  Obviously, they do not need the care and
-attention of the state-transformer monad.
+ Unboxed tuple types are subject to the same restrictions as
+other unboxed types; i.e. they may not be stored in polymorphic data
+structures or passed to polymorphic functions.
+
 </Para>
 </ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>Mutable:</Term>
 <ListItem>
+
 <Para>
-Arrays that may be changed or ``mutated.''  All the operations on them
-live within the state-transformer monad and the updates happen
-<Emphasis>in-place</Emphasis>.
+ Unboxed tuples may only be constructed as the direct result of
+a function, and may only be deconstructed with a <Literal>case</Literal> expression.
+eg. the following are valid:
+
+
+<ProgramListing>
+f x y = (# x+1, y-1 #)
+g x = case f x x of { (# a, b #) -&#62; a + b }
+</ProgramListing>
+
+
+but the following are invalid:
+
+
+<ProgramListing>
+f x y = g (# x, y #)
+g (# x, y #) = x + y
+</ProgramListing>
+
+
 </Para>
 </ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>``Static'' (in C land):</Term>
 <ListItem>
+
 <Para>
-A C routine may pass an <Literal>Addr&num;</Literal> pointer back into Haskell land.  There
-are then primitive operations with which you may merrily grab values
-over in C land, by indexing off the ``static'' pointer.
+ No variable can have an unboxed tuple type.  This is illegal:
+
+
+<ProgramListing>
+f :: (# Int, Int #) -&#62; (# Int, Int #)
+f x = x
+</ProgramListing>
+
+
+because <VarName>x</VarName> has an unboxed tuple type.
+
 </Para>
 </ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>``Stable'' pointers:</Term>
-<ListItem>
+
+</ItemizedList>
+
+</Para>
+
 <Para>
-If, for some reason, you wish to hand a Haskell pointer (i.e.,
-<Emphasis>not</Emphasis> an unboxed value) to a C routine, you first make the
-pointer ``stable,'' so that the garbage collector won't forget that it
-exists.  That is, GHC provides a safe way to pass Haskell pointers to
-C.
+Note: we may relax some of these restrictions in the future.
 </Para>
 
 <Para>
-Please see <XRef LinkEnd="glasgow-stablePtrs"> for more details.
+The <Literal>IO</Literal> and <Literal>ST</Literal> monads use unboxed
+tuples to avoid unnecessary allocation during sequences of operations.
 </Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>``Foreign objects'':</Term>
-<ListItem>
+
+</Sect2>
+
+<Sect2>
+<Title>Character and numeric types</Title>
+
+<IndexTerm><Primary>character types, primitive</Primary></IndexTerm>
+<IndexTerm><Primary>numeric types, primitive</Primary></IndexTerm>
+<IndexTerm><Primary>integer types, primitive</Primary></IndexTerm>
+<IndexTerm><Primary>floating point types, primitive</Primary></IndexTerm>
 <Para>
-A ``foreign object'' is a safe way to pass an external object (a
-C-allocated pointer, say) to Haskell and have Haskell do the Right
-Thing when it no longer references the object.  So, for example, C
-could pass a large bitmap over to Haskell and say ``please free this
-memory when you're done with it.''
+There are the following obvious primitive types:
 </Para>
 
+<ProgramListing>
+type Char#
+type Int#
+type Word#
+type Addr#
+type Float#
+type Double#
+type Int64#
+type Word64#
+</ProgramListing>
+
+<IndexTerm><Primary><literal>Char&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>Int&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>Word&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>Addr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>Float&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>Double&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>Int64&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>Word64&num;</literal></Primary></IndexTerm>
+
 <Para>
-Please see <XRef LinkEnd="glasgow-foreignObjs"> for more details.
+If you really want to know their exact equivalents in C, see
+<Filename>ghc/includes/StgTypes.h</Filename> in the GHC source tree.
 </Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
+
+<Para>
+Literals for these types may be written as follows:
 </Para>
 
 <Para>
-The libraries section gives more details on all these ``primitive
-array'' types and the operations on them, <XRef LinkEnd="ghc-prelude">.  Some of these extensions
-are also supported by Hugs, and the supporting libraries are described
-in the <ULink
-URL="libs.html"
->GHC/Hugs Extension Libraries</ULink
->
-document.
+
+<ProgramListing>
+1#              an Int#
+1.2#            a Float#
+1.34##          a Double#
+'a'#            a Char#; for weird characters, use e.g. '\o&#60;octal&#62;'#
+"a"#            an Addr# (a `char *'); only characters '\0'..'\255' allowed
+</ProgramListing>
+
+<IndexTerm><Primary>literals, primitive</Primary></IndexTerm>
+<IndexTerm><Primary>constants, primitive</Primary></IndexTerm>
+<IndexTerm><Primary>numbers, primitive</Primary></IndexTerm>
 </Para>
 
-</Sect1>
+</Sect2>
 
-<Sect1 id="glasgow-ccalls">
-<Title>Calling&nbsp;C directly from Haskell
-</Title>
+<Sect2>
+<Title>Comparison operations</Title>
 
 <Para>
-<IndexTerm><Primary>C calls (Glasgow extension)</Primary></IndexTerm>
-<IndexTerm><Primary>&lowbar;ccall&lowbar; (Glasgow extension)</Primary></IndexTerm>
-<IndexTerm><Primary>&lowbar;casm&lowbar; (Glasgow extension)</Primary></IndexTerm>
+<IndexTerm><Primary>comparisons, primitive</Primary></IndexTerm>
+<IndexTerm><Primary>operators, comparison</Primary></IndexTerm>
 </Para>
 
 <Para>
-GOOD ADVICE: Because this stuff is not Entirely Stable as far as names
-and things go, you would be well-advised to keep your C-callery
-corraled in a few modules, rather than sprinkled all over your code.
-It will then be quite easy to update later on.
+
+<ProgramListing>
+{&#62;,&#62;=,==,/=,&#60;,&#60;=}# :: Int# -&#62; Int# -&#62; Bool
+
+{gt,ge,eq,ne,lt,le}Char# :: Char# -&#62; Char# -&#62; Bool
+    -- ditto for Word# and Addr#
+</ProgramListing>
+
+<IndexTerm><Primary><literal>&#62;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>&#62;=&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>==&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>/=&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>&#60;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>&#60;=&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>gt&lcub;Char,Word,Addr&rcub;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>ge&lcub;Char,Word,Addr&rcub;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>eq&lcub;Char,Word,Addr&rcub;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>ne&lcub;Char,Word,Addr&rcub;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>lt&lcub;Char,Word,Addr&rcub;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>le&lcub;Char,Word,Addr&rcub;&num;</literal></Primary></IndexTerm>
 </Para>
 
-<Sect2 id="ccall-intro">
-<Title><Literal>&lowbar;ccall&lowbar;</Literal> and <Literal>&lowbar;casm&lowbar;</Literal>: an introduction
-</Title>
+</Sect2>
+
+<Sect2>
+<Title>Primitive-character operations</Title>
 
 <Para>
-The simplest way to use a simple C function
+<IndexTerm><Primary>characters, primitive operations</Primary></IndexTerm>
+<IndexTerm><Primary>operators, primitive character</Primary></IndexTerm>
 </Para>
 
 <Para>
 
 <ProgramListing>
-double fooC( FILE *in, char c, int i, double d, unsigned int u )
+ord# :: Char# -&#62; Int#
+chr# :: Int# -&#62; Char#
 </ProgramListing>
 
+<IndexTerm><Primary><literal>ord&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>chr&num;</literal></Primary></IndexTerm>
 </Para>
 
+</Sect2>
+
+<Sect2>
+<Title>Primitive-<Literal>Int</Literal> operations</Title>
+
 <Para>
-is to provide a Haskell wrapper:
+<IndexTerm><Primary>integers, primitive operations</Primary></IndexTerm>
+<IndexTerm><Primary>operators, primitive integer</Primary></IndexTerm>
 </Para>
 
 <Para>
 
 <ProgramListing>
-fooH :: Char -&#62; Int -&#62; Double -&#62; Word -&#62; IO Double
-fooH c i d w = _ccall_ fooC (``stdin''::Addr) c i d w
+{+,-,*,quotInt,remInt,gcdInt}# :: Int# -&#62; Int# -&#62; Int#
+negateInt# :: Int# -&#62; Int#
+
+iShiftL#, iShiftRA#, iShiftRL# :: Int# -&#62; Int# -&#62; Int#
+        -- shift left, right arithmetic, right logical
+
+addIntC#, subIntC#, mulIntC# :: Int# -> Int# -> (# Int#, Int# #)
+       -- add, subtract, multiply with carry
 </ProgramListing>
 
+<IndexTerm><Primary><literal>+&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>-&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>*&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>quotInt&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>remInt&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>gcdInt&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>iShiftL&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>iShiftRA&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>iShiftRL&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>addIntC&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>subIntC&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>mulIntC&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary>shift operations, integer</Primary></IndexTerm>
 </Para>
 
 <Para>
-The function <Literal>fooH</Literal> will unbox all of its arguments, call the C
-function <Literal>fooC</Literal> and box the corresponding arguments.
+<Emphasis>Note:</Emphasis> No error/overflow checking!
 </Para>
 
+</Sect2>
+
+<Sect2>
+<Title>Primitive-<Literal>Double</Literal> and <Literal>Float</Literal> operations</Title>
+
 <Para>
-One of the annoyances about <Literal>&lowbar;ccall&lowbar;</Literal>s is when the C types don't quite
-match the Haskell compiler's ideas.  For this, the <Literal>&lowbar;casm&lowbar;</Literal> variant
-may be just the ticket (NB: <Emphasis>no chance</Emphasis> of such code going
-through a native-code generator):
+<IndexTerm><Primary>floating point numbers, primitive</Primary></IndexTerm>
+<IndexTerm><Primary>operators, primitive floating point</Primary></IndexTerm>
 </Para>
 
 <Para>
 
 <ProgramListing>
-import Addr
-import CString
+{+,-,*,/}##         :: Double# -&#62; Double# -&#62; Double#
+{&#60;,&#60;=,==,/=,&#62;=,&#62;}## :: Double# -&#62; Double# -&#62; Bool
+negateDouble#       :: Double# -&#62; Double#
+double2Int#         :: Double# -&#62; Int#
+int2Double#         :: Int#    -&#62; Double#
+
+{plus,minux,times,divide}Float# :: Float# -&#62; Float# -&#62; Float#
+{gt,ge,eq,ne,lt,le}Float# :: Float# -&#62; Float# -&#62; Bool
+negateFloat#        :: Float# -&#62; Float#
+float2Int#          :: Float# -&#62; Int#
+int2Float#          :: Int#   -&#62; Float#
+</ProgramListing>
+
+</Para>
+
+<Para>
+<IndexTerm><Primary><literal>+&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>-&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>*&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>/&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>&#60;&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>&#60;=&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>==&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>=/&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>&#62;=&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>&#62;&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>negateDouble&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>double2Int&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>int2Double&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+<IndexTerm><Primary><literal>plusFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>minusFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>timesFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>divideFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>gtFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>geFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>eqFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>neFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>ltFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>leFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>negateFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>float2Int&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>int2Float&num;</literal></Primary></IndexTerm>
+</Para>
 
-oldGetEnv name
-  = _casm_ ``%r = getenv((char *) %0);'' name &#62;&#62;= \ litstring -&#62;
-    return (
-        if (litstring == nullAddr) then
-            Left ("Fail:oldGetEnv:"++name)
-        else
-            Right (unpackCString litstring)
-    )
+<Para>
+And a full complement of trigonometric functions:
+</Para>
+
+<Para>
+
+<ProgramListing>
+expDouble#      :: Double# -&#62; Double#
+logDouble#      :: Double# -&#62; Double#
+sqrtDouble#     :: Double# -&#62; Double#
+sinDouble#      :: Double# -&#62; Double#
+cosDouble#      :: Double# -&#62; Double#
+tanDouble#      :: Double# -&#62; Double#
+asinDouble#     :: Double# -&#62; Double#
+acosDouble#     :: Double# -&#62; Double#
+atanDouble#     :: Double# -&#62; Double#
+sinhDouble#     :: Double# -&#62; Double#
+coshDouble#     :: Double# -&#62; Double#
+tanhDouble#     :: Double# -&#62; Double#
+powerDouble#    :: Double# -&#62; Double# -&#62; Double#
 </ProgramListing>
 
+<IndexTerm><Primary>trigonometric functions, primitive</Primary></IndexTerm>
+</Para>
+
+<Para>
+similarly for <Literal>Float&num;</Literal>.
+</Para>
+
+<Para>
+There are two coercion functions for <Literal>Float&num;</Literal>/<Literal>Double&num;</Literal>:
 </Para>
 
 <Para>
-The first literal-literal argument to a <Literal>&lowbar;casm&lowbar;</Literal> is like a <Literal>printf</Literal>
-format: <Literal>&percnt;r</Literal> is replaced with the ``result,'' <Literal>&percnt;0</Literal>--<Literal>&percnt;n-1</Literal> are
-replaced with the 1st--nth arguments.  As you can see above, it is an
-easy way to do simple C&nbsp;casting.  Everything said about <Literal>&lowbar;ccall&lowbar;</Literal> goes
-for <Literal>&lowbar;casm&lowbar;</Literal> as well.
+
+<ProgramListing>
+float2Double#   :: Float# -&#62; Double#
+double2Float#   :: Double# -&#62; Float#
+</ProgramListing>
+
+<IndexTerm><Primary><literal>float2Double&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>double2Float&num;</literal></Primary></IndexTerm>
 </Para>
 
 <Para>
-The use of <Literal>&lowbar;casm&lowbar;</Literal> in your code does pose a problem to the compiler
-when it comes to generating an interface file for a freshly compiled
-module. Included in an interface file is the unfolding (if any) of a
-declaration. However, if a declaration's unfolding happens to contain
-a <Literal>&lowbar;casm&lowbar;</Literal>, its unfolding will <Emphasis>not</Emphasis> be emitted into the interface
-file even if it qualifies by all the other criteria. The reason why
-the compiler prevents this from happening is that unfolding <Literal>&lowbar;casm&lowbar;</Literal>s
-into an interface file unduly constrains how code that import your
-module have to be compiled. If an imported declaration is unfolded and
-it contains a <Literal>&lowbar;casm&lowbar;</Literal>, you now have to be using a compiler backend
-capable of dealing with it (i.e., the C compiler backend). If you are
-using the C compiler backend, the unfolded <Literal>&lowbar;casm&lowbar;</Literal> may still cause you
-problems since the C code snippet it contains may mention CPP symbols
-that were in scope when compiling the original module are not when
-compiling the importing module.
+The primitive version of <Function>decodeDouble</Function>
+(<Function>encodeDouble</Function> is implemented as an external C
+function):
 </Para>
 
 <Para>
-If you're willing to put up with the drawbacks of doing cross-module
-inlining of C code (GHC - A Better C Compiler :-), the option
-<Literal>-funfold-casms-in-hi-file</Literal> will turn off the default behaviour.
-<IndexTerm><Primary>-funfold-casms-in-hi-file option</Primary></IndexTerm>
+
+<ProgramListing>
+decodeDouble#   :: Double# -&#62; PrelNum.ReturnIntAndGMP
+</ProgramListing>
+
+<IndexTerm><Primary><literal>encodeDouble&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>decodeDouble&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+(And the same for <Literal>Float&num;</Literal>s.)
 </Para>
 
 </Sect2>
 
-<Sect2 id="glasgow-literal-literals">
-<Title>Literal-literals
+<Sect2 id="integer-operations">
+<Title>Operations on/for <Literal>Integers</Literal> (interface to GMP)
 </Title>
 
 <Para>
-<IndexTerm><Primary>Literal-literals</Primary></IndexTerm>
+<IndexTerm><Primary>arbitrary precision integers</Primary></IndexTerm>
+<IndexTerm><Primary>Integer, operations on</Primary></IndexTerm>
+</Para>
+
+<Para>
+We implement <Literal>Integers</Literal> (arbitrary-precision
+integers) using the GNU multiple-precision (GMP) package (version
+2.0.2).
+</Para>
+
+<Para>
+The data type for <Literal>Integer</Literal> is either a small
+integer, represented by an <Literal>Int</Literal>, or a large integer
+represented using the pieces required by GMP's
+<Literal>MP&lowbar;INT</Literal> in <Filename>gmp.h</Filename> (see
+<Filename>gmp.info</Filename> in
+<Filename>ghc/includes/runtime/gmp</Filename>).  It comes out as:
+</Para>
+
+<Para>
+
+<ProgramListing>
+data Integer = S# Int#             -- small integers
+             | J# Int# ByteArray#  -- large integers
+</ProgramListing>
+
+<IndexTerm><Primary>Integer type</Primary></IndexTerm> The primitive
+ops to support large <Literal>Integers</Literal> use the
+&ldquo;pieces&rdquo; of the representation, and are as follows:
+</Para>
+
+<Para>
+
+<ProgramListing>
+negateInteger#  :: Int# -&#62; ByteArray# -&#62; Integer
+
+{plus,minus,times}Integer#, gcdInteger#, 
+  quotInteger#, remInteger#, divExactInteger#
+       :: Int# -> ByteArray#
+        -> Int# -> ByteArray#
+        -> (# Int#, ByteArray# #)
+
+cmpInteger# 
+       :: Int# -> ByteArray#
+        -> Int# -> ByteArray#
+        -> Int# -- -1 for &#60;; 0 for ==; +1 for >
+
+cmpIntegerInt# 
+       :: Int# -> ByteArray#
+        -> Int#
+        -> Int# -- -1 for &#60;; 0 for ==; +1 for >
+
+gcdIntegerInt# :: 
+       :: Int# -> ByteArray#
+        -> Int#
+        -> Int#
+
+divModInteger#, quotRemInteger#
+        :: Int# -> ByteArray#
+        -> Int# -> ByteArray#
+        -> (# Int#, ByteArray#,
+                  Int#, ByteArray# #)
+
+integer2Int# :: Int# -> ByteArray# -> Int#
+
+int2Integer#  :: Int#  -> Integer -- NB: no error-checking on these two!
+word2Integer# :: Word# -> Integer
+
+addr2Integer# :: Addr# -> Integer
+        -- the Addr# is taken to be a `char *' string
+        -- to be converted into an Integer.
+</ProgramListing>
+
+<IndexTerm><Primary><literal>negateInteger&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>plusInteger&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>minusInteger&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>timesInteger&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>quotInteger&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>remInteger&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>gcdInteger&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>gcdIntegerInt&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>divExactInteger&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>cmpInteger&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>divModInteger&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>quotRemInteger&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>integer2Int&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>int2Integer&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>word2Integer&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>addr2Integer&num;</literal></Primary></IndexTerm>
 </Para>
 
+</Sect2>
+
+<Sect2>
+<Title>Words and addresses</Title>
+
 <Para>
-The literal-literal argument to <Literal>&lowbar;casm&lowbar;</Literal> can be made use of separately
-from the <Literal>&lowbar;casm&lowbar;</Literal> construct itself. Indeed, we've already used it:
+<IndexTerm><Primary>word, primitive type</Primary></IndexTerm>
+<IndexTerm><Primary>address, primitive type</Primary></IndexTerm>
+<IndexTerm><Primary>unsigned integer, primitive type</Primary></IndexTerm>
+<IndexTerm><Primary>pointer, primitive type</Primary></IndexTerm>
 </Para>
 
 <Para>
+A <Literal>Word&num;</Literal> is used for bit-twiddling operations.
+It is the same size as an <Literal>Int&num;</Literal>, but has no sign
+nor any arithmetic operations.
 
 <ProgramListing>
-fooH :: Char -&#62; Int -&#62; Double -&#62; Word -&#62; IO Double
-fooH c i d w = _ccall_ fooC (``stdin''::Addr) c i d w
+type Word#      -- Same size/etc as Int# but *unsigned*
+type Addr#      -- A pointer from outside the "Haskell world" (from C, probably);
+                -- described under "arrays"
 </ProgramListing>
 
+<IndexTerm><Primary><literal>Word&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>Addr&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+<Literal>Word&num;</Literal>s and <Literal>Addr&num;</Literal>s have
+the usual comparison operations.  Other
+unboxed-<Literal>Word</Literal> ops (bit-twiddling and coercions):
 </Para>
 
 <Para>
-The first argument that's passed to <Literal>fooC</Literal> is given as a literal-literal,
-that is, a literal chunk of C code that will be inserted into the generated
-<Literal>.hc</Literal> code at the right place.
+
+<ProgramListing>
+{gt,ge,eq,ne,lt,le}Word# :: Word# -> Word# -> Bool
+
+and#, or#, xor# :: Word# -> Word# -> Word#
+        -- standard bit ops.
+
+quotWord#, remWord# :: Word# -> Word# -> Word#
+        -- word (i.e. unsigned) versions are different from int
+        -- versions, so we have to provide these explicitly.
+
+not# :: Word# -> Word#
+
+shiftL#, shiftRL# :: Word# -> Int# -> Word#
+        -- shift left, right logical
+
+int2Word#       :: Int#  -> Word# -- just a cast, really
+word2Int#       :: Word# -> Int#
+</ProgramListing>
+
+<IndexTerm><Primary>bit operations, Word and Addr</Primary></IndexTerm>
+<IndexTerm><Primary><literal>gtWord&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>geWord&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>eqWord&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>neWord&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>ltWord&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>leWord&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>and&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>or&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>xor&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>not&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>quotWord&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>remWord&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>shiftL&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>shiftRA&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>shiftRL&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>int2Word&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>word2Int&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+Unboxed-<Literal>Addr</Literal> ops (C casts, really):
+
+<ProgramListing>
+{gt,ge,eq,ne,lt,le}Addr# :: Addr# -> Addr# -> Bool
+
+int2Addr#       :: Int#  -> Addr#
+addr2Int#       :: Addr# -> Int#
+addr2Integer#   :: Addr# -> (# Int#, ByteArray# #)
+</ProgramListing>
+
+<IndexTerm><Primary><literal>gtAddr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>geAddr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>eqAddr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>neAddr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>ltAddr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>leAddr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>int2Addr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>addr2Int&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>addr2Integer&num;</literal></Primary></IndexTerm>
 </Para>
 
 <Para>
-A literal-literal is restricted to having a type that's an instance of
-the <Literal>CCallable</Literal> class, see <XRef LinkEnd="ccall-gotchas">
-for more information.
+The casts between <Literal>Int&num;</Literal>,
+<Literal>Word&num;</Literal> and <Literal>Addr&num;</Literal>
+correspond to null operations at the machine level, but are required
+to keep the Haskell type checker happy.
 </Para>
 
 <Para>
-Notice that literal-literals are by their very nature unfriendly to
-native code generators, so exercise judgement about whether or not to
-make use of them in your code.
+Operations for indexing off of C pointers
+(<Literal>Addr&num;</Literal>s) to snatch values are listed under
+&ldquo;arrays&rdquo;.
 </Para>
 
 </Sect2>
 
-<Sect2 id="glasgow-foreign-headers">
-<Title>Using function headers
-</Title>
+<Sect2>
+<Title>Arrays</Title>
 
 <Para>
-<IndexTerm><Primary>C calls, function headers</Primary></IndexTerm>
+<IndexTerm><Primary>arrays, primitive</Primary></IndexTerm>
 </Para>
 
 <Para>
-When generating C (using the <Literal>-fvia-C</Literal> directive), one can assist the
-C compiler in detecting type errors by using the <Literal>-&num;include</Literal> directive
-to provide <Literal>.h</Literal> files containing function headers.
+The type <Literal>Array&num; elt</Literal> is the type of primitive,
+unpointed arrays of values of type <Literal>elt</Literal>.
 </Para>
 
 <Para>
-For example,
+
+<ProgramListing>
+type Array# elt
+</ProgramListing>
+
+<IndexTerm><Primary><literal>Array&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+<Literal>Array&num;</Literal> is more primitive than a Haskell
+array&mdash;indeed, the Haskell <Literal>Array</Literal> interface is
+implemented using <Literal>Array&num;</Literal>&mdash;in that an
+<Literal>Array&num;</Literal> is indexed only by
+<Literal>Int&num;</Literal>s, starting at zero.  It is also more
+primitive by virtue of being unboxed.  That doesn't mean that it isn't
+a heap-allocated object&mdash;of course, it is.  Rather, being unboxed
+means that it is represented by a pointer to the array itself, and not
+to a thunk which will evaluate to the array (or to bottom).  The
+components of an <Literal>Array&num;</Literal> are themselves boxed.
+</Para>
+
+<Para>
+The type <Literal>ByteArray&num;</Literal> is similar to
+<Literal>Array&num;</Literal>, except that it contains just a string
+of (non-pointer) bytes.
 </Para>
 
 <Para>
 
 <ProgramListing>
-typedef unsigned long *StgForeignObj;
-typedef long StgInt;
-
-void          initialiseEFS (StgInt size);
-StgInt        terminateEFS (void);
-StgForeignObj emptyEFS(void);
-StgForeignObj updateEFS (StgForeignObj a, StgInt i, StgInt x);
-StgInt        lookupEFS (StgForeignObj a, StgInt i);
-</ProgramListing>
-
-</Para>
-
-<Para>
-You can find appropriate definitions for <Literal>StgInt</Literal>, <Literal>StgForeignObj</Literal>,
-etc using <Literal>gcc</Literal> on your architecture by consulting
-<Literal>ghc/includes/StgTypes.h</Literal>.  The following table summarises the
-relationship between Haskell types and C types.
-</Para>
-
-<Para>
-
-<InformalTable>
-<TGroup Cols="2">
-<ColSpec Align="Left" Colsep="0">
-<ColSpec Align="Left" Colsep="0">
-<TBody>
-<Row>
-<Entry><Emphasis>C type name</Emphasis> </Entry>
-<Entry> <Emphasis>Haskell Type</Emphasis> </Entry>
-</Row>
-
-<Row>
-<Entry>
-<Literal>StgChar</Literal> </Entry>
-<Entry> <Literal>Char&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgInt</Literal> </Entry>
-<Entry> <Literal>Int&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgWord</Literal> </Entry>
-<Entry> <Literal>Word&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgAddr</Literal> </Entry>
-<Entry> <Literal>Addr&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgFloat</Literal> </Entry>
-<Entry> <Literal>Float&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgDouble</Literal> </Entry>
-<Entry> <Literal>Double&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgArray</Literal> </Entry>
-<Entry> <Literal>Array&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgByteArray</Literal> </Entry>
-<Entry> <Literal>ByteArray&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgArray</Literal> </Entry>
-<Entry> <Literal>MutableArray&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgByteArray</Literal> </Entry>
-<Entry> <Literal>MutableByteArray&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgStablePtr</Literal> </Entry>
-<Entry> <Literal>StablePtr&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgForeignObj</Literal> </Entry>
-<Entry> <Literal>ForeignObj&num;</Literal></Entry>
-</Row>
-</TBody>
-
-</TGroup>
-</InformalTable>
-</Para>
-
-<Para>
-Note that this approach is only <Emphasis>essential</Emphasis> for returning
-<Literal>float</Literal>s (or if <Literal>sizeof(int) != sizeof(int *)</Literal> on your
-architecture) but is a Good Thing for anyone who cares about writing
-solid code.  You're crazy not to do it.
+type ByteArray#
+</ProgramListing>
+
+<IndexTerm><Primary><literal>ByteArray&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+Arrays of these types are useful when a Haskell program wishes to
+construct a value to pass to a C procedure. It is also possible to use
+them to build (say) arrays of unboxed characters for internal use in a
+Haskell program.  Given these uses, <Literal>ByteArray&num;</Literal>
+is deliberately a bit vague about the type of its components.
+Operations are provided to extract values of type
+<Literal>Char&num;</Literal>, <Literal>Int&num;</Literal>,
+<Literal>Float&num;</Literal>, <Literal>Double&num;</Literal>, and
+<Literal>Addr&num;</Literal> from arbitrary offsets within a
+<Literal>ByteArray&num;</Literal>.  (For type
+<Literal>Foo&num;</Literal>, the $i$th offset gets you the $i$th
+<Literal>Foo&num;</Literal>, not the <Literal>Foo&num;</Literal> at
+byte-position $i$.  Mumble.)  (If you want a
+<Literal>Word&num;</Literal>, grab an <Literal>Int&num;</Literal>,
+then coerce it.)
+</Para>
+
+<Para>
+Lastly, we have static byte-arrays, of type
+<Literal>Addr&num;</Literal> &lsqb;mentioned previously].  (Remember
+the duality between arrays and pointers in C.)  Arrays of this types
+are represented by a pointer to an array in the world outside Haskell,
+so this pointer is not followed by the garbage collector.  In other
+respects they are just like <Literal>ByteArray&num;</Literal>.  They
+are only needed in order to pass values from C to Haskell.
 </Para>
 
 </Sect2>
 
-<Sect2 id="glasgow-stablePtrs">
-<Title>Subverting automatic unboxing with ``stable pointers''
-</Title>
+<Sect2>
+<Title>Reading and writing</Title>
 
 <Para>
-<IndexTerm><Primary>stable pointers (Glasgow extension)</Primary></IndexTerm>
+Primitive arrays are linear, and indexed starting at zero.
 </Para>
 
 <Para>
-The arguments of a <Literal>&lowbar;ccall&lowbar;</Literal> are automatically unboxed before the
-call.  There are two reasons why this is usually the Right Thing to
-do:
+The size and indices of a <Literal>ByteArray&num;</Literal>, <Literal>Addr&num;</Literal>, and
+<Literal>MutableByteArray&num;</Literal> are all in bytes.  It's up to the program to
+calculate the correct byte offset from the start of the array.  This
+allows a <Literal>ByteArray&num;</Literal> to contain a mixture of values of different
+type, which is often needed when preparing data for and unpicking
+results from C.  (Umm&hellip;not true of indices&hellip;WDP 95/09)
 </Para>
 
 <Para>
+<Emphasis>Should we provide some <Literal>sizeOfDouble&num;</Literal> constants?</Emphasis>
+</Para>
 
-<ItemizedList>
-<ListItem>
+<Para>
+Out-of-range errors on indexing should be caught by the code which
+uses the primitive operation; the primitive operations themselves do
+<Emphasis>not</Emphasis> check for out-of-range indexes. The intention is that the
+primitive ops compile to one machine instruction or thereabouts.
+</Para>
 
 <Para>
-C is a strict language: it would be excessively tedious to pass
-unevaluated arguments and require the C programmer to force their
-evaluation before using them.
+We use the terms &ldquo;reading&rdquo; and &ldquo;writing&rdquo; to refer to accessing
+<Emphasis>mutable</Emphasis> arrays (see <XRef LinkEnd="sect-mutable">), and
+&ldquo;indexing&rdquo; to refer to reading a value from an <Emphasis>immutable</Emphasis>
+array.
+</Para>
+
+<Para>
+Immutable byte arrays are straightforward to index (all indices in bytes):
+
+<ProgramListing>
+indexCharArray#   :: ByteArray# -> Int# -> Char#
+indexIntArray#    :: ByteArray# -> Int# -> Int#
+indexAddrArray#   :: ByteArray# -> Int# -> Addr#
+indexFloatArray#  :: ByteArray# -> Int# -> Float#
+indexDoubleArray# :: ByteArray# -> Int# -> Double#
+
+indexCharOffAddr#   :: Addr# -> Int# -> Char#
+indexIntOffAddr#    :: Addr# -> Int# -> Int#
+indexFloatOffAddr#  :: Addr# -> Int# -> Float#
+indexDoubleOffAddr# :: Addr# -> Int# -> Double#
+indexAddrOffAddr#   :: Addr# -> Int# -> Addr#
+ -- Get an Addr# from an Addr# offset
+</ProgramListing>
 
+<IndexTerm><Primary><literal>indexCharArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexIntArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexAddrArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexFloatArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexDoubleArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexCharOffAddr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexIntOffAddr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexFloatOffAddr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexDoubleOffAddr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexAddrOffAddr&num;</literal></Primary></IndexTerm>
 </Para>
-</ListItem>
-<ListItem>
 
 <Para>
- Boxed values are stored on the Haskell heap and may be moved
-within the heap if a garbage collection occurs&mdash;that is, pointers
-to boxed objects are not <Emphasis>stable</Emphasis>.
+The last of these, <Function>indexAddrOffAddr&num;</Function>, extracts an <Literal>Addr&num;</Literal> using an offset
+from another <Literal>Addr&num;</Literal>, thereby providing the ability to follow a chain of
+C pointers.
 </Para>
-</ListItem>
 
-</ItemizedList>
+<Para>
+Something a bit more interesting goes on when indexing arrays of boxed
+objects, because the result is simply the boxed object. So presumably
+it should be entered&mdash;we never usually return an unevaluated
+object!  This is a pain: primitive ops aren't supposed to do
+complicated things like enter objects.  The current solution is to
+return a single element unboxed tuple (see <XRef LinkEnd="unboxed-tuples">).
+</Para>
 
+<Para>
+
+<ProgramListing>
+indexArray#       :: Array# elt -> Int# -> (# elt #)
+</ProgramListing>
+
+<IndexTerm><Primary><literal>indexArray&num;</literal></Primary></IndexTerm>
 </Para>
 
+</Sect2>
+
+<Sect2>
+<Title>The state type</Title>
+
 <Para>
-It is possible to subvert the unboxing process by creating a ``stable
-pointer'' to a value and passing the stable pointer instead.  For
-example, to pass/return an integer lazily to C functions <Literal>storeC</Literal> and
-<Literal>fetchC</Literal>, one might write:
+<IndexTerm><Primary><literal>state, primitive type</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>State&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+The primitive type <Literal>State&num;</Literal> represents the state of a state
+transformer.  It is parameterised on the desired type of state, which
+serves to keep states from distinct threads distinct from one another.
+But the <Emphasis>only</Emphasis> effect of this parameterisation is in the type
+system: all values of type <Literal>State&num;</Literal> are represented in the same way.
+Indeed, they are all represented by nothing at all!  The code
+generator &ldquo;knows&rdquo; to generate no code, and allocate no registers
+etc, for primitive states.
 </Para>
 
 <Para>
 
 <ProgramListing>
-storeH :: Int -&#62; IO ()
-storeH x = makeStablePtr x              &#62;&#62;= \ stable_x -&#62;
-           _ccall_ storeC stable_x
+type State# s
+</ProgramListing>
+
+</Para>
+
+<Para>
+The type <Literal>GHC.RealWorld</Literal> is truly opaque: there are no values defined
+of this type, and no operations over it.  It is &ldquo;primitive&rdquo; in that
+sense - but it is <Emphasis>not unlifted!</Emphasis> Its only role in life is to be
+the type which distinguishes the <Literal>IO</Literal> state transformer.
+</Para>
+
+<Para>
 
-fetchH :: IO Int
-fetchH x = _ccall_ fetchC               &#62;&#62;= \ stable_x -&#62;
-           deRefStablePtr stable_x      &#62;&#62;= \ x -&#62;
-           freeStablePtr stable_x       &#62;&#62;
-           return x
+<ProgramListing>
+data RealWorld
 </ProgramListing>
 
 </Para>
 
+</Sect2>
+
+<Sect2>
+<Title>State of the world</Title>
+
 <Para>
-The garbage collector will refrain from throwing a stable pointer away
-until you explicitly call one of the following from C or Haskell.
+A single, primitive, value of type <Literal>State&num; RealWorld</Literal> is provided.
 </Para>
 
 <Para>
 
 <ProgramListing>
-void freeStablePointer( StgStablePtr stablePtrToToss )
-freeStablePtr :: StablePtr a -&#62; IO ()
+realWorld# :: State# RealWorld
 </ProgramListing>
 
+<IndexTerm><Primary>realWorld&num; state object</Primary></IndexTerm>
 </Para>
 
 <Para>
-As with the use of <Literal>free</Literal> in C programs, GREAT CARE SHOULD BE
-EXERCISED to ensure these functions are called at the right time: too
-early and you get dangling references (and, if you're lucky, an error
-message from the runtime system); too late and you get space leaks.
+(Note: in the compiler, not a <Literal>PrimOp</Literal>; just a mucho magic
+<Literal>Id</Literal>. Exported from <Literal>GHC</Literal>, though).
 </Para>
 
+</Sect2>
+
+<Sect2 id="sect-mutable">
+<Title>Mutable arrays</Title>
+
 <Para>
-And to force evaluation of the argument within <Literal>fooC</Literal>, one would
-call one of the following C functions (according to type of argument).
+<IndexTerm><Primary>mutable arrays</Primary></IndexTerm>
+<IndexTerm><Primary>arrays, mutable</Primary></IndexTerm>
+Corresponding to <Literal>Array&num;</Literal> and <Literal>ByteArray&num;</Literal>, we have the types of
+mutable versions of each.  In each case, the representation is a
+pointer to a suitable block of (mutable) heap-allocated storage.
 </Para>
 
 <Para>
 
 <ProgramListing>
-void     performIO  ( StgStablePtr stableIndex /* StablePtr s (IO ()) */ );
-StgInt   enterInt   ( StgStablePtr stableIndex /* StablePtr s Int */ );
-StgFloat enterFloat ( StgStablePtr stableIndex /* StablePtr s Float */ );
+type MutableArray# s elt
+type MutableByteArray# s
 </ProgramListing>
 
+<IndexTerm><Primary><literal>MutableArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>MutableByteArray&num;</literal></Primary></IndexTerm>
 </Para>
 
+<Sect3>
+<Title>Allocation</Title>
+
 <Para>
-<IndexTerm><Primary>performIO</Primary></IndexTerm>
-<IndexTerm><Primary>enterInt</Primary></IndexTerm>
-<IndexTerm><Primary>enterFloat</Primary></IndexTerm>
+<IndexTerm><Primary>mutable arrays, allocation</Primary></IndexTerm>
+<IndexTerm><Primary>arrays, allocation</Primary></IndexTerm>
+<IndexTerm><Primary>allocation, of mutable arrays</Primary></IndexTerm>
 </Para>
 
 <Para>
-Nota Bene: <Literal>&lowbar;ccall&lowbar;GC&lowbar;</Literal><IndexTerm><Primary>&lowbar;ccall&lowbar;GC&lowbar;</Primary></IndexTerm> must be used if any of
-these functions are used.
+Mutable arrays can be allocated. Only pointer-arrays are initialised;
+arrays of non-pointers are filled in by &ldquo;user code&rdquo; rather than by
+the array-allocation primitive.  Reason: only the pointer case has to
+worry about GC striking with a partly-initialised array.
 </Para>
 
-</Sect2>
+<Para>
 
-<Sect2 id="glasgow-foreignObjs">
-<Title>Foreign objects: pointing outside the Haskell heap
-</Title>
+<ProgramListing>
+newArray#       :: Int# -> elt -> State# s -> (# State# s, MutableArray# s elt #)
+
+newCharArray#   :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
+newIntArray#    :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
+newAddrArray#   :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
+newFloatArray#  :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
+newDoubleArray# :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
+</ProgramListing>
+
+<IndexTerm><Primary><literal>newArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>newCharArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>newIntArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>newAddrArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>newFloatArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>newDoubleArray&num;</literal></Primary></IndexTerm>
+</Para>
 
 <Para>
-<IndexTerm><Primary>foreign objects (Glasgow extension)</Primary></IndexTerm>
+The size of a <Literal>ByteArray&num;</Literal> is given in bytes.
 </Para>
 
+</Sect3>
+
+<Sect3>
+<Title>Reading and writing</Title>
+
 <Para>
-There are two types that <Literal>ghc</Literal> programs can use to reference
-(heap-allocated) objects outside the Haskell world: <Literal>Addr</Literal> and
-<Literal>ForeignObj</Literal>.
+<IndexTerm><Primary>arrays, reading and writing</Primary></IndexTerm>
 </Para>
 
 <Para>
-If you use <Literal>Addr</Literal>, it is up to you to the programmer to arrange
-allocation and deallocation of the objects.
+
+<ProgramListing>
+readArray#       :: MutableArray# s elt -> Int# -> State# s -> (# State# s, elt #)
+readCharArray#   :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #)
+readIntArray#    :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
+readAddrArray#   :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Addr# #)
+readFloatArray#  :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Float# #)
+readDoubleArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Double# #)
+
+writeArray#       :: MutableArray# s elt -> Int# -> elt     -> State# s -> State# s
+writeCharArray#   :: MutableByteArray# s -> Int# -> Char#   -> State# s -> State# s
+writeIntArray#    :: MutableByteArray# s -> Int# -> Int#    -> State# s -> State# s
+writeAddrArray#   :: MutableByteArray# s -> Int# -> Addr#   -> State# s -> State# s
+writeFloatArray#  :: MutableByteArray# s -> Int# -> Float#  -> State# s -> State# s
+writeDoubleArray# :: MutableByteArray# s -> Int# -> Double# -> State# s -> State# s
+</ProgramListing>
+
+<IndexTerm><Primary><literal>readArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>readCharArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>readIntArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>readAddrArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>readFloatArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>readDoubleArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>writeArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>writeCharArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>writeIntArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>writeAddrArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>writeFloatArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>writeDoubleArray&num;</literal></Primary></IndexTerm>
 </Para>
 
+</Sect3>
+
+<Sect3>
+<Title>Equality</Title>
+
 <Para>
-If you use <Literal>ForeignObj</Literal>, <Literal>ghc</Literal>'s garbage collector will call upon the
-user-supplied <Emphasis>finaliser</Emphasis> function to free the object when the
-Haskell world no longer can access the object.  (An object is
-associated with a finaliser function when the abstract
-Haskell type <Literal>ForeignObj</Literal> is created). The finaliser function is
-expressed in C, and is passed as argument the object:
+<IndexTerm><Primary>arrays, testing for equality</Primary></IndexTerm>
+</Para>
+
+<Para>
+One can take &ldquo;equality&rdquo; of mutable arrays.  What is compared is the
+<Emphasis>name</Emphasis> or reference to the mutable array, not its contents.
 </Para>
 
 <Para>
 
 <ProgramListing>
-void foreignFinaliser ( StgForeignObj fo )
+sameMutableArray#     :: MutableArray# s elt -> MutableArray# s elt -> Bool
+sameMutableByteArray# :: MutableByteArray# s -> MutableByteArray# s -> Bool
 </ProgramListing>
 
+<IndexTerm><Primary><literal>sameMutableArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>sameMutableByteArray&num;</literal></Primary></IndexTerm>
+</Para>
+
+</Sect3>
+
+<Sect3>
+<Title>Freezing mutable arrays</Title>
+
+<Para>
+<IndexTerm><Primary>arrays, freezing mutable</Primary></IndexTerm>
+<IndexTerm><Primary>freezing mutable arrays</Primary></IndexTerm>
+<IndexTerm><Primary>mutable arrays, freezing</Primary></IndexTerm>
 </Para>
 
 <Para>
-when the Haskell world can no longer access the object.  Since
-<Literal>ForeignObj</Literal>s only get released when a garbage collection occurs, we
-provide ways of triggering a garbage collection from within C and from
-within Haskell.
+Only unsafe-freeze has a primitive.  (Safe freeze is done directly in Haskell
+by copying the array and then using <Function>unsafeFreeze</Function>.)
 </Para>
 
 <Para>
 
 <ProgramListing>
-void GarbageCollect()
-performGC :: IO ()
+unsafeFreezeArray#     :: MutableArray# s elt -> State# s -> (# State# s, Array# s elt #)
+unsafeFreezeByteArray# :: MutableByteArray# s -> State# s -> (# State# s, ByteArray# #)
 </ProgramListing>
 
+<IndexTerm><Primary><literal>unsafeFreezeArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>unsafeFreezeByteArray&num;</literal></Primary></IndexTerm>
+</Para>
+
+</Sect3>
+
+</Sect2>
+
+<Sect2>
+<Title>Synchronizing variables (M-vars)</Title>
+
+<Para>
+<IndexTerm><Primary>synchronising variables (M-vars)</Primary></IndexTerm>
+<IndexTerm><Primary>M-Vars</Primary></IndexTerm>
+</Para>
+
+<Para>
+Synchronising variables are the primitive type used to implement
+Concurrent Haskell's MVars (see the Concurrent Haskell paper for
+the operational behaviour of these operations).
 </Para>
 
 <Para>
-More information on the programmers' interface to <Literal>ForeignObj</Literal> can be
-found in the library documentation.
+
+<ProgramListing>
+type MVar# s elt        -- primitive
+
+newMVar#    :: State# s -> (# State# s, MVar# s elt #)
+takeMVar#   :: SynchVar# s elt -> State# s -> (# State# s, elt #)
+putMVar#    :: SynchVar# s elt -> State# s -> State# s
+</ProgramListing>
+
+<IndexTerm><Primary><literal>SynchVar&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>newSynchVar&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>takeMVar</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>putMVar</literal></Primary></IndexTerm>
 </Para>
 
 </Sect2>
 
-<Sect2 id="glasgow-avoiding-monads">
-<Title>Avoiding monads
+</Sect1>
+
+<Sect1 id="glasgow-ST-monad">
+<Title>Primitive state-transformer monad
+</Title>
+
+<Para>
+<IndexTerm><Primary>state transformers (Glasgow extensions)</Primary></IndexTerm>
+<IndexTerm><Primary>ST monad (Glasgow extension)</Primary></IndexTerm>
+</Para>
+
+<Para>
+This monad underlies our implementation of arrays, mutable and
+immutable, and our implementation of I/O, including &ldquo;C calls&rdquo;.
+</Para>
+
+<Para>
+The <Literal>ST</Literal> library, which provides access to the
+<Function>ST</Function> monad, is described in <xref
+linkend="sec-ST">.
+</Para>
+
+</Sect1>
+
+<Sect1 id="glasgow-prim-arrays">
+<Title>Primitive arrays, mutable and otherwise
 </Title>
 
 <Para>
-<IndexTerm><Primary>C calls to `pure C'</Primary></IndexTerm>
-<IndexTerm><Primary>unsafePerformIO</Primary></IndexTerm>
+<IndexTerm><Primary>primitive arrays (Glasgow extension)</Primary></IndexTerm>
+<IndexTerm><Primary>arrays, primitive (Glasgow extension)</Primary></IndexTerm>
 </Para>
 
 <Para>
-The <Literal>&lowbar;ccall&lowbar;</Literal> construct is part of the <Literal>IO</Literal> monad because 9 out of 10
-uses will be to call imperative functions with side effects such as
-<Literal>printf</Literal>.  Use of the monad ensures that these operations happen in a
-predictable order in spite of laziness and compiler optimisations.
+GHC knows about quite a few flavours of Large Swathes of Bytes.
 </Para>
 
 <Para>
-To avoid having to be in the monad to call a C function, it is
-possible to use <Literal>unsafePerformIO</Literal>, which is available from the
-<Literal>IOExts</Literal> module.  There are three situations where one might like to
-call a C function from outside the IO world:
+First, GHC distinguishes between primitive arrays of (boxed) Haskell
+objects (type <Literal>Array&num; obj</Literal>) and primitive arrays of bytes (type
+<Literal>ByteArray&num;</Literal>).
 </Para>
 
 <Para>
+Second, it distinguishes between&hellip;
+<VariableList>
 
-<ItemizedList>
+<VarListEntry>
+<Term>Immutable:</Term>
 <ListItem>
-
 <Para>
-Calling a function with no side-effects:
-
-<ProgramListing>
-atan2d :: Double -&#62; Double -&#62; Double
-atan2d y x = unsafePerformIO (_ccall_ atan2d y x)
-
-sincosd :: Double -&#62; (Double, Double)
-sincosd x = unsafePerformIO $ do
-        da &#60;- newDoubleArray (0, 1)
-        _casm_ ``sincosd( %0, &amp;((double *)%1[0]), &amp;((double *)%1[1]) );'' x da
-        s &#60;- readDoubleArray da 0
-        c &#60;- readDoubleArray da 1
-        return (s, c)
-</ProgramListing>
-
-
+Arrays that do not change (as with &ldquo;standard&rdquo; Haskell arrays); you
+can only read from them.  Obviously, they do not need the care and
+attention of the state-transformer monad.
 </Para>
 </ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Mutable:</Term>
 <ListItem>
-
 <Para>
- Calling a set of functions which have side-effects but which can
-be used in a purely functional manner.
-
-For example, an imperative implementation of a purely functional
-lookup-table might be accessed using the following functions.
-
-
-<ProgramListing>
-empty  :: EFS x
-update :: EFS x -&#62; Int -&#62; x -&#62; EFS x
-lookup :: EFS a -&#62; Int -&#62; a
-
-empty = unsafePerformIO (_ccall_ emptyEFS)
-
-update a i x = unsafePerformIO $
-        makeStablePtr x         &#62;&#62;= \ stable_x -&#62;
-        _ccall_ updateEFS a i stable_x
-
-lookup a i = unsafePerformIO $
-        _ccall_ lookupEFS a i   &#62;&#62;= \ stable_x -&#62;
-        deRefStablePtr stable_x
-</ProgramListing>
-
-
-You will almost always want to use <Literal>ForeignObj</Literal>s with this.
-
+Arrays that may be changed or &ldquo;mutated.&rdquo;  All the operations on them
+live within the state-transformer monad and the updates happen
+<Emphasis>in-place</Emphasis>.
 </Para>
 </ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>&ldquo;Static&rdquo; (in C land):</Term>
 <ListItem>
-
 <Para>
- Calling a side-effecting function even though the results will
-be unpredictable.  For example the <Literal>trace</Literal> function is defined by:
-
-
-<ProgramListing>
-trace :: String -&#62; a -&#62; a
-trace string expr
-  = unsafePerformIO (
-        ((_ccall_ PreTraceHook sTDERR{-msg-}):: IO ())  &#62;&#62;
-        fputs sTDERR string                             &#62;&#62;
-        ((_ccall_ PostTraceHook sTDERR{-msg-}):: IO ()) &#62;&#62;
-        return expr )
-  where
-    sTDERR = (``stderr'' :: Addr)
-</ProgramListing>
-
-
-(This kind of use is not highly recommended&mdash;it is only really
-useful in debugging code.)
+A C routine may pass an <Literal>Addr&num;</Literal> pointer back into Haskell land.  There
+are then primitive operations with which you may merrily grab values
+over in C land, by indexing off the &ldquo;static&rdquo; pointer.
 </Para>
 </ListItem>
-
-</ItemizedList>
-
+</VarListEntry>
+<VarListEntry>
+<Term>&ldquo;Stable&rdquo; pointers:</Term>
+<ListItem>
+<Para>
+If, for some reason, you wish to hand a Haskell pointer (i.e.,
+<Emphasis>not</Emphasis> an unboxed value) to a C routine, you first make the
+pointer &ldquo;stable,&rdquo; so that the garbage collector won't forget that it
+exists.  That is, GHC provides a safe way to pass Haskell pointers to
+C.
 </Para>
 
-</Sect2>
-
-<Sect2 id="ccall-gotchas">
-<Title>C-calling ``gotchas'' checklist
-</Title>
-
 <Para>
-<IndexTerm><Primary>C call dangers</Primary></IndexTerm>
-<IndexTerm><Primary>CCallable</Primary></IndexTerm>
-<IndexTerm><Primary>CReturnable</Primary></IndexTerm>
+Please see <XRef LinkEnd="sec-stable-pointers"> for more details.
 </Para>
-
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>&ldquo;Foreign objects&rdquo;:</Term>
+<ListItem>
 <Para>
-And some advice, too.
+A &ldquo;foreign object&rdquo; is a safe way to pass an external object (a
+C-allocated pointer, say) to Haskell and have Haskell do the Right
+Thing when it no longer references the object.  So, for example, C
+could pass a large bitmap over to Haskell and say &ldquo;please free this
+memory when you're done with it.&rdquo;
 </Para>
 
 <Para>
-
-<ItemizedList>
-<ListItem>
+Please see <XRef LinkEnd="sec-ForeignObj"> for more details.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
 
 <Para>
- For modules that use <Literal>&lowbar;ccall&lowbar;</Literal>s, etc., compile with
-<Literal>-fvia-C</Literal>.<IndexTerm><Primary>-fvia-C option</Primary></IndexTerm> You don't have to, but you should.
+The libraries documentatation gives more details on all these
+&ldquo;primitive array&rdquo; types and the operations on them.
+</Para>
+
+</Sect1>
 
-Also, use the <Literal>-&num;include "prototypes.h"</Literal> flag (hack) to inform the C
-compiler of the fully-prototyped types of all the C functions you
-call.  (<XRef LinkEnd="glasgow-foreign-headers"> says more about this&hellip;)
 
-This scheme is the <Emphasis>only</Emphasis> way that you will get <Emphasis>any</Emphasis>
-typechecking of your <Literal>&lowbar;ccall&lowbar;</Literal>s.  (It shouldn't be that way, but&hellip;).
-GHC will pass the flag <Literal>-Wimplicit</Literal> to gcc so that you'll get warnings
-if any <Literal>&lowbar;ccall&lowbar;</Literal>ed functions have no prototypes.
+<Sect1 id="pattern-guards">
+<Title>Pattern guards</Title>
 
+<Para>
+<IndexTerm><Primary>Pattern guards (Glasgow extension)</Primary></IndexTerm>
+The discussion that follows is an abbreviated version of Simon Peyton Jones's original <ULink URL="http://research.microsoft.com/~simonpj/Haskell/guards.html">proposal</ULink>. (Note that the proposal was written before pattern guards were implemented, so refers to them as unimplemented.)
 </Para>
-</ListItem>
-<ListItem>
 
 <Para>
-Try to avoid <Literal>&lowbar;ccall&lowbar;</Literal>s to C&nbsp;functions that take <Literal>float</Literal>
-arguments or return <Literal>float</Literal> results.  Reason: if you do, you will
-become entangled in (ANSI?) C's rules for when arguments/results are
-promoted to <Literal>doubles</Literal>.  It's a nightmare and just not worth it.
-Use <Literal>doubles</Literal> if possible.
+Suppose we have an abstract data type of finite maps, with a
+lookup operation:
 
-If you do use <Literal>floats</Literal>, check and re-check that the right thing is
-happening.  Perhaps compile with <Literal>-keep-hc-file-too</Literal> and look at
-the intermediate C (<Literal>.hc</Literal> file).
+<ProgramListing>
+lookup :: FiniteMap -> Int -> Maybe Int
+</ProgramListing>
 
+The lookup returns <Function>Nothing</Function> if the supplied key is not in the domain of the mapping, and <Function>(Just v)</Function> otherwise,
+where <VarName>v</VarName> is the value that the key maps to.  Now consider the following definition:
 </Para>
-</ListItem>
-<ListItem>
-
-<Para>
- The compiler uses two non-standard type-classes when
-type-checking the arguments and results of <Literal>&lowbar;ccall&lowbar;</Literal>: the arguments
-(respectively result) of <Literal>&lowbar;ccall&lowbar;</Literal> must be instances of the class
-<Literal>CCallable</Literal> (respectively <Literal>CReturnable</Literal>).  Both classes may be
-imported from the module <Literal>CCall</Literal>, but this should only be
-necessary if you want to define a new instance.  (Neither class
-defines any methods&mdash;their only function is to keep the
-type-checker happy.)
-
-The type checker must be able to figure out just which of the
-C-callable/returnable types is being used.  If it can't, you have to
-add type signatures. For example,
-
-
-<ProgramListing>
-f x = _ccall_ foo x
-</ProgramListing>
-
-
-is not good enough, because the compiler can't work out what type <Literal>x</Literal>
-is, nor what type the <Literal>&lowbar;ccall&lowbar;</Literal> returns.  You have to write, say:
-
-
-<ProgramListing>
-f :: Int -&#62; IO Double
-f x = _ccall_ foo x
-</ProgramListing>
-
-
-This table summarises the standard instances of these classes.
-
-<InformalTable>
-<TGroup Cols="4">
-<ColSpec Align="Left" Colsep="0">
-<ColSpec Align="Left" Colsep="0">
-<ColSpec Align="Left" Colsep="0">
-<ColSpec Align="Left" Colsep="0">
-<TBody>
-<Row>
-<Entry><Emphasis>Type</Emphasis> </Entry>
-<Entry><Emphasis>CCallable</Emphasis></Entry>
-<Entry><Emphasis>CReturnable</Emphasis> </Entry>
-<Entry><Emphasis>Which is probably&hellip;</Emphasis> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Char</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>unsigned char</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Int</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>long int</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Word</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>unsigned long int</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Addr</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>void *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Float</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>float</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Double</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>double</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>()</Literal> </Entry>
-<Entry> No </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>void</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>[Char]</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>char *</Literal> (null-terminated) </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Array</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>ByteArray</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>MutableArray</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>MutableByteArray</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>State</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> nothing!</Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StablePtr</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>ForeignObjs</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> see later </Entry>
-</Row>
-
-</TBody>
-
-</TGroup>
-</InformalTable>
-
-Actually, the <Literal>Word</Literal> type is defined as being the same size as a
-pointer on the target architecture, which is <Emphasis>probably</Emphasis>
-<Literal>unsigned long int</Literal>.
-
-The brave and careful programmer can add their own instances of these
-classes for the following types:
-
 
-<ItemizedList>
-<ListItem>
+<ProgramListing>
+clunky env var1 var2 | ok1 && ok2 = val1 + val2
+| otherwise  = var1 + var2
+where
+  m1 = lookup env var1
+  m2 = lookup env var2
+  ok1 = maybeToBool m1
+  ok2 = maybeToBool m2
+  val1 = expectJust m1
+  val2 = expectJust m2
+</ProgramListing>
 
 <Para>
-A <Emphasis>boxed-primitive</Emphasis> type may be made an instance of both
-<Literal>CCallable</Literal> and <Literal>CReturnable</Literal>.
-
-A boxed primitive type is any data type with a
-single unary constructor with a single primitive argument.  For
-example, the following are all boxed primitive types:
-
+The auxiliary functions are 
+</Para>
 
 <ProgramListing>
-Int
-Double
-data XDisplay = XDisplay Addr#
-data EFS a = EFS# ForeignObj#
+maybeToBool :: Maybe a -&gt; Bool
+maybeToBool (Just x) = True
+maybeToBool Nothing  = False
+
+expectJust :: Maybe a -&gt; a
+expectJust (Just x) = x
+expectJust Nothing  = error "Unexpected Nothing"
 </ProgramListing>
 
+<Para>
+What is <Function>clunky</Function> doing? The guard <Literal>ok1 &&
+ok2</Literal> checks that both lookups succeed, using
+<Function>maybeToBool</Function> to convert the <Function>Maybe</Function>
+types to booleans. The (lazily evaluated) <Function>expectJust</Function>
+calls extract the values from the results of the lookups, and binds the
+returned values to <VarName>val1</VarName> and <VarName>val2</VarName>
+respectively.  If either lookup fails, then clunky takes the
+<Literal>otherwise</Literal> case and returns the sum of its arguments.
+</Para>
 
+<Para>
+This is certainly legal Haskell, but it is a tremendously verbose and
+un-obvious way to achieve the desired effect.  Arguably, a more direct way
+to write clunky would be to use case expressions:
+</Para>
 
 <ProgramListing>
-instance CCallable   (EFS a)
-instance CReturnable (EFS a)
+clunky env var1 var1 = case lookup env var1 of
+  Nothing -&gt; fail
+  Just val1 -&gt; case lookup env var2 of
+    Nothing -&gt; fail
+    Just val2 -&gt; val1 + val2
+where
+  fail = val1 + val2
 </ProgramListing>
 
-
+<Para>
+This is a bit shorter, but hardly better.  Of course, we can rewrite any set
+of pattern-matching, guarded equations as case expressions; that is
+precisely what the compiler does when compiling equations! The reason that
+Haskell provides guarded equations is because they allow us to write down
+the cases we want to consider, one at a time, independently of each other. 
+This structure is hidden in the case version.  Two of the right-hand sides
+are really the same (<Function>fail</Function>), and the whole expression
+tends to become more and more indented. 
 </Para>
-</ListItem>
-<ListItem>
 
 <Para>
- Any datatype with a single nullary constructor may be made an
-instance of <Literal>CReturnable</Literal>.  For example:
-
+Here is how I would write clunky:
+</Para>
 
 <ProgramListing>
-data MyVoid = MyVoid
-instance CReturnable MyVoid
+clunky env var1 var1
+  | Just val1 &lt;- lookup env var1
+  , Just val2 &lt;- lookup env var2
+  = val1 + val2
+...other equations for clunky...
 </ProgramListing>
 
-
+<Para>
+The semantics should be clear enough.  The qualifers are matched in order. 
+For a <Literal>&lt;-</Literal> qualifier, which I call a pattern guard, the
+right hand side is evaluated and matched against the pattern on the left. 
+If the match fails then the whole guard fails and the next equation is
+tried.  If it succeeds, then the appropriate binding takes place, and the
+next qualifier is matched, in the augmented environment.  Unlike list
+comprehensions, however, the type of the expression to the right of the
+<Literal>&lt;-</Literal> is the same as the type of the pattern to its
+left.  The bindings introduced by pattern guards scope over all the
+remaining guard qualifiers, and over the right hand side of the equation.
 </Para>
-</ListItem>
-<ListItem>
 
 <Para>
- As at version 2.09, <Literal>String</Literal> (i.e., <Literal>[Char]</Literal>) is still
-not a <Literal>CReturnable</Literal> type.
+Just as with list comprehensions, boolean expressions can be freely mixed
+with among the pattern guards.  For example:
+</Para>
+
+<ProgramListing>
+f x | [y] <- x
+    , y > 3
+    , Just z <- h y
+    = ...
+</ProgramListing>
 
-Also, the now-builtin type <Literal>PackedString</Literal> is neither
-<Literal>CCallable</Literal> nor <Literal>CReturnable</Literal>.  (But there are functions in
-the PackedString interface to let you get at the necessary bits&hellip;)
+<Para>
+Haskell's current guards therefore emerge as a special case, in which the
+qualifier list has just one element, a boolean expression.
 </Para>
-</ListItem>
+</Sect1>
 
-</ItemizedList>
+  <sect1 id="sec-ffi">
+    <title>The foreign interface</title>
+
+    <para>The foreign interface consists of the following components:</para>
+
+    <itemizedlist>
+      <listitem>
+       <para>The Foreign Function Interface language specification
+       (included in this manual, in <xref linkend="ffi">).</para>
+      </listitem>
+
+      <listitem>
+       <para>The <literal>Foreign</literal> module (see <xref
+       linkend="sec-Foreign">) collects together several interfaces
+       which are useful in specifying foreign language
+       interfaces, including the following:</para>
+
+       <itemizedlist>
+         <listitem>
+           <para>The <literal>ForeignObj</literal> module (see <xref
+           linkend="sec-ForeignObj">), for managing pointers from
+           Haskell into the outside world.</para>
+         </listitem>
+      
+         <listitem>
+           <para>The <literal>StablePtr</literal> module (see <xref
+           linkend="sec-stable-pointers">), for managing pointers
+           into Haskell from the outside world.</para>
+         </listitem>
+      
+         <listitem>
+           <para>The <literal>CTypes</literal> module (see <xref
+           linkend="sec-CTypes">) gives Haskell equivalents for the
+           standard C datatypes, for use in making Haskell bindings
+           to existing C libraries.</para>
+         </listitem>
+      
+         <listitem>
+           <para>The <literal>CTypesISO</literal> module (see <xref
+           linkend="sec-CTypesISO">) gives Haskell equivalents for C
+           types defined by the ISO C standard.</para>
+         </listitem>
+      
+         <listitem>
+           <para>The <literal>Storable</literal> library, for
+           primitive marshalling of data types between Haskell and
+           the foreign language.</para>
+         </listitem>
+       </itemizedlist>
+
+      </listitem>
+    </itemizedlist>
+
+<para>The following sections also give some hints and tips on the use
+of the foreign function interface in GHC.</para>
 
+<Sect2 id="glasgow-foreign-headers">
+<Title>Using function headers
+</Title>
 
+<Para>
+<IndexTerm><Primary>C calls, function headers</Primary></IndexTerm>
 </Para>
-</ListItem>
-<ListItem>
 
 <Para>
- The code-generator will complain if you attempt to use <Literal>&percnt;r</Literal> in
-a <Literal>&lowbar;casm&lowbar;</Literal> whose result type is <Literal>IO ()</Literal>; or if you don't use <Literal>&percnt;r</Literal>
-<Emphasis>precisely</Emphasis> once for any other result type.  These messages are
-supposed to be helpful and catch bugs&mdash;please tell us if they wreck
-your life.
-
+When generating C (using the <Option>-fvia-C</Option> directive), one can assist the
+C compiler in detecting type errors by using the <Command>-&num;include</Command> directive
+to provide <Filename>.h</Filename> files containing function headers.
 </Para>
-</ListItem>
-<ListItem>
 
 <Para>
- If you call out to C code which may trigger the Haskell garbage
-collector or create new threads (examples of this later&hellip;), then you
-must use the <Literal>&lowbar;ccall&lowbar;GC&lowbar;</Literal><IndexTerm><Primary>&lowbar;ccall&lowbar;GC&lowbar; primitive</Primary></IndexTerm> or
-<Literal>&lowbar;casm&lowbar;GC&lowbar;</Literal><IndexTerm><Primary>&lowbar;casm&lowbar;GC&lowbar; primitive</Primary></IndexTerm> variant of C-calls.  (This
-does not work with the native code generator - use <Literal>\fvia-C</Literal>.) This
-stuff is hairy with a capital H!
+For example,
 </Para>
-</ListItem>
 
-</ItemizedList>
+<Para>
 
+<ProgramListing>
+#include "HsFFI.h"
+
+void         initialiseEFS (HsInt size);
+HsInt        terminateEFS (void);
+HsForeignObj emptyEFS(void);
+HsForeignObj updateEFS (HsForeignObj a, HsInt i, HsInt x);
+HsInt        lookupEFS (HsForeignObj a, HsInt i);
+</ProgramListing>
 </Para>
 
+      <para>The types <literal>HsInt</literal>,
+      <literal>HsForeignObj</literal> etc. are described in <xref
+      linkend="sec-mapping-table">.</Para>
+
+      <Para>Note that this approach is only
+      <Emphasis>essential</Emphasis> for returning
+      <Literal>float</Literal>s (or if <Literal>sizeof(int) !=
+      sizeof(int *)</Literal> on your architecture) but is a Good
+      Thing for anyone who cares about writing solid code.  You're
+      crazy not to do it.</Para>
+
 </Sect2>
 
 </Sect1>
@@ -1156,12 +1732,11 @@ stuff is hairy with a capital H!
 </Title>
 
 <Para>
-This section documents GHC's implementation of multi-paramter type
+This section documents GHC's implementation of multi-parameter type
 classes.  There's lots of background in the paper <ULink
-URL="http://www.dcs.gla.ac.uk/~simonpj/multi.ps.gz"
->Type classes: exploring the design space</ULink
-> (Simon Peyton
-Jones, Mark Jones, Erik Meijer).
+URL="http://research.microsoft.com/~simonpj/multi.ps.gz" >Type
+classes: exploring the design space</ULink > (Simon Peyton Jones, Mark
+Jones, Erik Meijer).
 </Para>
 
 <Para>
@@ -1190,7 +1765,7 @@ type:
 <Para>
 
 <ProgramListing>
-  forall tv1..tvn (c1, ...,cn) =&#62; type
+  forall tv1..tvn (c1, ...,cn) => type
 </ProgramListing>
 
 </Para>
@@ -1218,7 +1793,7 @@ ambiguity. Here, for example, is an illegal type:
 
 
 <ProgramListing>
-  forall a. Eq a =&#62; Int
+  forall a. Eq a => Int
 </ProgramListing>
 
 
@@ -1242,7 +1817,7 @@ universally quantified type variable <Literal>b</Literal>:
 
 
 <ProgramListing>
-  forall a. C a b =&#62; burble
+  forall a. C a b => burble
 </ProgramListing>
 
 
@@ -1251,7 +1826,7 @@ mention <Literal>a</Literal>:
 
 
 <ProgramListing>
-  forall a. Eq b =&#62; burble
+  forall a. Eq b => burble
 </ProgramListing>
 
 
@@ -1283,8 +1858,8 @@ are perfectly OK
 <Para>
 
 <ProgramListing>
-  f :: Eq (m a) =&#62; [m a] -&#62; [m a]
-  g :: Eq [a] =&#62; ...
+  f :: Eq (m a) => [m a] -> [m a]
+  g :: Eq [a] => ...
 </ProgramListing>
 
 </Para>
@@ -1309,7 +1884,7 @@ This choice recovers principal types, a property that Haskell 1.4 does not have.
 
 <ProgramListing>
   class Collection c a where
-    union :: c a -&#62; c a -&#62; c a
+    union :: c a -> c a -> c a
     ...etc.
 </ProgramListing>
 
@@ -1327,10 +1902,10 @@ this is OK:
 
 <ProgramListing>
   class C a where {
-    op :: D b =&#62; a -&#62; b -&#62; b
+    op :: D b => a -> b -> b
   }
 
-  class C a =&#62; D a where { ... }
+  class C a => D a where { ... }
 </ProgramListing>
 
 
@@ -1349,11 +1924,11 @@ be acyclic</Emphasis>.  So these class declarations are OK:
 
 
 <ProgramListing>
-  class Functor (m k) =&#62; FiniteMap m k where
+  class Functor (m k) => FiniteMap m k where
     ...
 
-  class (Monad m, Monad (t m)) =&#62; Transform t m where
-    lift :: m a -&#62; (t m) a
+  class (Monad m, Monad (t m)) => Transform t m where
+    lift :: m a -> (t m) a
 </ProgramListing>
 
 
@@ -1371,7 +1946,7 @@ Thus:
 
 <ProgramListing>
   class Collection c a where
-    mapC :: Collection c b =&#62; (a-&#62;b) -&#62; c a -&#62; c b
+    mapC :: Collection c b => (a->b) -> c a -> c b
 </ProgramListing>
 
 
@@ -1382,7 +1957,7 @@ is OK because the constraint <Literal>(Collection a b)</Literal> mentions
 
 <ProgramListing>
   class C a where
-    op :: Eq a =&#62; (a,b) -&#62; (a,b)
+    op :: Eq a => (a,b) -> (a,b)
 </ProgramListing>
 
 
@@ -1393,8 +1968,8 @@ superclass context:
 
 
 <ProgramListing>
-  class Eq a =&#62; C a where
-    op ::(a,b) -&#62; (a,b)
+  class Eq a => C a where
+    op ::(a,b) -> (a,b)
 </ProgramListing>
 
 
@@ -1414,7 +1989,7 @@ the class type variables</Emphasis>.  For example:
 <ProgramListing>
   class Coll s a where
     empty  :: s
-    insert :: s -&#62; a -&#62; s
+    insert :: s -> a -> s
 </ProgramListing>
 
 
@@ -1429,7 +2004,7 @@ example, <Literal>Coll</Literal> might be rewritten
 <ProgramListing>
   class Coll s a where
     empty  :: s a
-    insert :: s a -&#62; a -&#62; s a
+    insert :: s a -> a -> s a
 </ProgramListing>
 
 
@@ -1443,8 +2018,8 @@ class like this:
   class CollE s where
     empty  :: s
 
-  class CollE s =&#62; Coll s a where
-    insert :: s -&#62; a -&#62; s
+  class CollE s => Coll s a where
+    insert :: s -> a -> s
 </ProgramListing>
 
 
@@ -1457,7 +2032,7 @@ class like this:
 
 </Sect2>
 
-<Sect2>
+<Sect2 id="instance-decls">
 <Title>Instance declarations</Title>
 
 <Para>
@@ -1471,15 +2046,15 @@ declarations
 
 
 <ProgramListing>
-  instance context1 =&#62; C type1 where ...
-  instance context2 =&#62; C type2 where ...
+  instance context1 => C type1 where ...
+  instance context2 => C type2 where ...
 </ProgramListing>
 
 
 "overlap" if <Literal>type1</Literal> and <Literal>type2</Literal> unify
 
 However, if you give the command line option
-<Literal>-fallow-overlapping-instances</Literal><IndexTerm><Primary>-fallow-overlapping-instances
+<Option>-fallow-overlapping-instances</Option><IndexTerm><Primary>-fallow-overlapping-instances
 option</Primary></IndexTerm> then two overlapping instance declarations are permitted
 iff
 
@@ -1548,7 +2123,7 @@ change that decision, at least for <Literal>Main</Literal>.)
 <Para>
  <Emphasis>There are no restrictions on the type in an instance
 <Emphasis>head</Emphasis>, except that at least one must not be a type variable</Emphasis>.
-The instance "head" is the bit after the "=&#62;" in an instance decl. For
+The instance "head" is the bit after the "=>" in an instance decl. For
 example, these are OK:
 
 
@@ -1577,7 +2152,7 @@ loop if it wasn't excluded:
 
 
 <ProgramListing>
-  instance C a =&#62; C a where ...
+  instance C a => C a where ...
 </ProgramListing>
 
 
@@ -1598,9 +2173,9 @@ effect of a "class synonym":
 
 
 <ProgramListing>
-  class (C1 a, C2 a, C3 a) =&#62; C a where { }
+  class (C1 a, C2 a, C3 a) => C a where { }
 
-  instance (C1 a, C2 a, C3 a) =&#62; C a where { }
+  instance (C1 a, C2 a, C3 a) => C a where { }
 </ProgramListing>
 
 
@@ -1608,7 +2183,7 @@ This allows you to write shorter signatures:
 
 
 <ProgramListing>
-  f :: C a =&#62; ...
+  f :: C a => ...
 </ProgramListing>
 
 
@@ -1616,13 +2191,13 @@ instead of
 
 
 <ProgramListing>
-  f :: (C1 a, C2 a, C3 a) =&#62; ...
+  f :: (C1 a, C2 a, C3 a) => ...
 </ProgramListing>
 
 
 I'm on the lookout for a simple rule that preserves decidability while
 allowing these idioms.  The experimental flag
-<Literal>-fallow-undecidable-instances</Literal><IndexTerm><Primary>-fallow-undecidable-instances
+<Option>-fallow-undecidable-instances</Option><IndexTerm><Primary>-fallow-undecidable-instances
 option</Primary></IndexTerm> lifts this restriction, allowing all the types in an
 instance head to be type variables.
 
@@ -1675,7 +2250,7 @@ be type variables</Emphasis>. Thus
 
 
 <ProgramListing>
-instance C a b =&#62; Eq (a,b) where ...
+instance C a b => Eq (a,b) where ...
 </ProgramListing>
 
 
@@ -1683,7 +2258,7 @@ is OK, but
 
 
 <ProgramListing>
-instance C Int b =&#62; Foo b where ...
+instance C Int b => Foo b where ...
 </ProgramListing>
 
 
@@ -1692,11 +2267,11 @@ reduction terminates.
 
 Voluminous correspondence on the Haskell mailing list has convinced me
 that it's worth experimenting with a more liberal rule.  If you use
-the flag <Literal>-fallow-undecidable-instances</Literal> you can use arbitrary
+the flag <Option>-fallow-undecidable-instances</Option> can use arbitrary
 types in an instance context.  Termination is ensured by having a
 fixed-depth recursion stack.  If you exceed the stack depth you get a
 sort of backtrace, and the opportunity to increase the stack depth
-with <Literal>-fcontext-stack</Literal><Emphasis>N</Emphasis>.
+with <Option>-fcontext-stack</Option><Emphasis>N</Emphasis>.
 
 </Para>
 </ListItem>
@@ -1721,7 +2296,7 @@ syntax for this now agrees with Hugs's, namely:
 <Para>
 
 <ProgramListing>
-        forall a b. (Ord a, Eq  b) =&#62; a -&#62; b -&#62; a
+        forall a b. (Ord a, Eq  b) => a -> b -> a
 </ProgramListing>
 
 </Para>
@@ -1739,7 +2314,7 @@ allows us to say exactly what this means.  For example:
 <Para>
 
 <ProgramListing>
-        g :: b -&#62; b
+        g :: b -> b
 </ProgramListing>
 
 </Para>
@@ -1751,7 +2326,7 @@ means this:
 <Para>
 
 <ProgramListing>
-        g :: forall b. (b -&#62; b)
+        g :: forall b. (b -> b)
 </ProgramListing>
 
 </Para>
@@ -1772,13 +2347,13 @@ the types of the constructor arguments.  Here are several examples:
 <Para>
 
 <ProgramListing>
-data T a = T1 (forall b. b -&#62; b -&#62; b) a
+data T a = T1 (forall b. b -> b -> b) a
 
-data MonadT m = MkMonad { return :: forall a. a -&#62; m a,
-                          bind   :: forall a b. m a -&#62; (a -&#62; m b) -&#62; m b
+data MonadT m = MkMonad { return :: forall a. a -> m a,
+                          bind   :: forall a b. m a -> (a -> m b) -> m b
                         }
 
-newtype Swizzle = MkSwizzle (Ord a =&#62; [a] -&#62; [a])
+newtype Swizzle = MkSwizzle (Ord a => [a] -> [a])
 </ProgramListing>
 
 </Para>
@@ -1791,11 +2366,11 @@ types, in which there is a for-all in the argument types.:
 <Para>
 
 <ProgramListing>
-T1 :: forall a. (forall b. b -&#62; b -&#62; b) -&#62; a -&#62; T1 a
-MkMonad :: forall m. (forall a. a -&#62; m a)
-                  -&#62; (forall a b. m a -&#62; (a -&#62; m b) -&#62; m b)
-                  -&#62; MonadT m
-MkSwizzle :: (Ord a =&#62; [a] -&#62; [a]) -&#62; Swizzle
+T1 :: forall a. (forall b. b -> b -> b) -> a -> T a
+MkMonad :: forall m. (forall a. a -> m a)
+                  -> (forall a b. m a -> (a -> m b) -> m b)
+                  -> MonadT m
+MkSwizzle :: (Ord a => [a] -> [a]) -> Swizzle
 </ProgramListing>
 
 </Para>
@@ -1803,7 +2378,7 @@ MkSwizzle :: (Ord a =&#62; [a] -&#62; [a]) -&#62; Swizzle
 <Para>
 Notice that you don't need to use a <Literal>forall</Literal> if there's an
 explicit context.  For example in the first argument of the
-constructor <Literal>MkSwizzle</Literal>, an implicit "<Literal>forall a.</Literal>" is
+constructor <Function>MkSwizzle</Function>, an implicit "<Literal>forall a.</Literal>" is
 prefixed to the argument type.  The implicit <Literal>forall</Literal>
 quantifies all type variables that are not already in scope, and are
 mentioned in the type quantified over.
@@ -1814,13 +2389,13 @@ As for type signatures, implicit quantification happens for non-overloaded
 types too.  So if you write this:
 
 <ProgramListing>
-  data T a = MkT (Either a b) (b -&#62; b)
+  data T a = MkT (Either a b) (b -> b)
 </ProgramListing>
 
 it's just as if you had written this:
 
 <ProgramListing>
-  data T a = MkT (forall b. Either a b) (forall b. b -&#62; b)
+  data T a = MkT (forall b. Either a b) (forall b. b -> b)
 </ProgramListing>
 
 That is, since the type variable <Literal>b</Literal> isn't in scope, it's
@@ -1842,15 +2417,15 @@ the constructor to suitable values, just as usual.  For example,
 <Para>
 
 <ProgramListing>
-(T1 (\xy-&#62;x) 3) :: T Int
+(T1 (\xy->x) 3) :: T Int
 
 (MkSwizzle sort)    :: Swizzle
 (MkSwizzle reverse) :: Swizzle
 
 (let r x = Just x
      b m k = case m of
-                Just y -&#62; k y
-                Nothing -&#62; Nothing
+                Just y -> k y
+                Nothing -> Nothing
   in
   MkMonad r b) :: MonadT Maybe
 </ProgramListing>
@@ -1859,7 +2434,7 @@ the constructor to suitable values, just as usual.  For example,
 
 <Para>
 The type of the argument can, as usual, be more general than the type
-required, as <Literal>(MkSwizzle reverse)</Literal> shows.  (<Literal>reverse</Literal>
+required, as <Literal>(MkSwizzle reverse)</Literal> shows.  (<Function>reverse</Function>
 does not need the <Literal>Ord</Literal> constraint.)
 </Para>
 
@@ -1876,23 +2451,23 @@ polymorphic types.  For example:
 <Para>
 
 <ProgramListing>
-        f :: T a -&#62; a -&#62; (a, Char)
+        f :: T a -> a -> (a, Char)
         f (T1 f k) x = (f k x, f 'c' 'd')
 
-        g :: (Ord a, Ord b) =&#62; Swizzle -&#62; [a] -&#62; (a -&#62; b) -&#62; [b]
+        g :: (Ord a, Ord b) => Swizzle -> [a] -> (a -> b) -> [b]
         g (MkSwizzle s) xs f = s (map f (s xs))
 
-        h :: MonadT m -&#62; [m a] -&#62; m [a]
+        h :: MonadT m -> [m a] -> m [a]
         h m [] = return m []
-        h m (x:xs) = bind m x           $ \y -&#62;
-                      bind m (h m xs)   $ \ys -&#62;
+        h m (x:xs) = bind m x           $ \y ->
+                      bind m (h m xs)   $ \ys ->
                       return m (y:ys)
 </ProgramListing>
 
 </Para>
 
 <Para>
-In the function <Literal>h</Literal> we use the record selectors <Literal>return</Literal>
+In the function <Function>h</Function> we use the record selectors <Literal>return</Literal>
 and <Literal>bind</Literal> to extract the polymorphic bind and return functions
 from the <Literal>MonadT</Literal> data structure, rather than using pattern
 matching.
@@ -1905,7 +2480,7 @@ For example:
 <ProgramListing>
         newtype TIM s a = TIM (ST s (Maybe a))
 
-        runTIM :: (forall s. TIM s a) -&#62; Maybe a
+        runTIM :: (forall s. TIM s a) -> Maybe a
         runTIM (TIM m) = runST m
 </ProgramListing>
 
@@ -1917,8 +2492,8 @@ an argument of type <Literal>(forall s. TIM s a)</Literal>.  Instead you
 must bind the variable and pattern match in the right hand side:
 
 <ProgramListing>
-        runTIM :: (forall s. TIM s a) -&#62; Maybe a
-        runTIM tm = case tm of { TIM m -&#62; runST m }
+        runTIM :: (forall s. TIM s a) -> Maybe a
+        runTIM tm = case tm of { TIM m -> runST m }
 </ProgramListing>
 
 The <Literal>tm</Literal> on the right hand side is (invisibly) instantiated, like
@@ -1954,7 +2529,7 @@ this rule</Emphasis>.  The restriction makes type inference feasible.
 
 <Para>
 In the illegal example, the sub-expression <Literal>MkSwizzle</Literal> has the
-polymorphic type <Literal>(Ord b =&#62; [b] -&#62; [b]) -&#62; Swizzle</Literal> and is not
+polymorphic type <Literal>(Ord b => [b] -> [b]) -> Swizzle</Literal> and is not
 a sub-expression of an enclosing application.  On the other hand, this
 expression is OK:
 </Para>
@@ -1962,14 +2537,14 @@ expression is OK:
 <Para>
 
 <ProgramListing>
-        map (T1 (\a b -&#62; a)) [1,2,3]
+        map (T1 (\a b -> a)) [1,2,3]
 </ProgramListing>
 
 </Para>
 
 <Para>
-even though it involves a partial application of <Literal>T1</Literal>, because
-the sub-expression <Literal>T1 (\a b -&#62; a)</Literal> has type <Literal>Int -&#62; T
+even though it involves a partial application of <Function>T1</Function>, because
+the sub-expression <Literal>T1 (\a b -> a)</Literal> has type <Literal>Int -> T
 Int</Literal>.
 </Para>
 
@@ -1981,7 +2556,7 @@ Int</Literal>.
 
 <Para>
 Once you have data constructors with universally-quantified fields, or
-constants such as <Literal>runST</Literal> that have rank-2 types, it isn't long
+constants such as <Constant>runST</Constant> that have rank-2 types, it isn't long
 before you discover that you need more!  Consider:
 </Para>
 
@@ -1994,13 +2569,13 @@ before you discover that you need more!  Consider:
 </Para>
 
 <Para>
-<Literal>mkTs</Literal> is a fuction that constructs some values of type
+<Function>mkTs</Function> is a fuction that constructs some values of type
 <Literal>T</Literal>, using some pieces passed to it.  The trouble is that since
 <Literal>f</Literal> is a function argument, Haskell assumes that it is
-monomorphic, so we'll get a type error when applying <Literal>T1</Literal> to
+monomorphic, so we'll get a type error when applying <Function>T1</Function> to
 it.  This is a rather silly example, but the problem really bites in
 practice.  Lots of people trip over the fact that you can't make
-"wrappers functions" for <Literal>runST</Literal> for exactly the same reason.
+"wrappers functions" for <Constant>runST</Constant> for exactly the same reason.
 In short, it is impossible to build abstractions around functions with
 rank-2 types.
 </Para>
@@ -2014,7 +2589,7 @@ constructors), thus:
 <Para>
 
 <ProgramListing>
-  mkTs :: (forall b. b -&#62; b -&#62; b) -&#62; a -&#62; [T a]
+  mkTs :: (forall b. b -> b -> b) -> a -> [T a]
   mkTs f x y = [T1 f x, T1 f y]
 </ProgramListing>
 
@@ -2022,9 +2597,9 @@ constructors), thus:
 
 <Para>
 This type signature tells the compiler to attribute <Literal>f</Literal> with
-the polymorphic type <Literal>(forall b. b -&#62; b -&#62; b)</Literal> when type
-checking the body of <Literal>mkTs</Literal>, so now the application of
-<Literal>T1</Literal> is fine.
+the polymorphic type <Literal>(forall b. b -> b -> b)</Literal> when type
+checking the body of <Function>mkTs</Function>, so now the application of
+<Function>T1</Function> is fine.
 </Para>
 
 <Para>
@@ -2042,10 +2617,10 @@ grammar:
 
 
 <ProgramListing>
-   rank2type ::= [forall tyvars .] [context =&#62;] funty
-   funty     ::= ([forall tyvars .] [context =&#62;] ty) -&#62; funty
-               | ty
-   ty        ::= ...current Haskell monotype syntax...
+rank2type ::= [forall tyvars .] [context =>] funty
+funty     ::= ([forall tyvars .] [context =>] ty) -> funty
+            | ty
+ty        ::= ...current Haskell monotype syntax...
 </ProgramListing>
 
 
@@ -2060,12 +2635,12 @@ or at the top level of a function argument.
  There is a restriction on the definition of a function whose
 type signature is a rank-2 type: the polymorphic arguments must be
 matched on the left hand side of the "<Literal>=</Literal>" sign.  You can't
-define <Literal>mkTs</Literal> like this:
+define <Function>mkTs</Function> like this:
 
 
 <ProgramListing>
-  mkTs :: (forall b. b -&#62; b -&#62; b) -&#62; a -&#62; [T a]
-  mkTs = \ f x y -&#62; [T1 f x, T1 f y]
+mkTs :: (forall b. b -> b -> b) -> a -> [T a]
+mkTs = \ f x y -> [T1 f x, T1 f y]
 </ProgramListing>
 
 
@@ -2082,6 +2657,53 @@ rank-2 types as applied to data constructors.
 
 </Sect2>
 
+
+<Sect2 id="hoist">
+<Title>Type synonyms and hoisting
+</Title>
+
+<Para>
+GHC also allows you to write a <Literal>forall</Literal> in a type synonym, thus:
+<ProgramListing>
+  type Discard a = forall b. a -> b -> a
+
+  f :: Discard a
+  f x y = x
+</ProgramListing>
+However, it is often convenient to use these sort of synonyms at the right hand
+end of an arrow, thus:
+<ProgramListing>
+  type Discard a = forall b. a -> b -> a
+
+  g :: Int -> Discard Int
+  g x y z = x+y
+</ProgramListing>
+Simply expanding the type synonym would give
+<ProgramListing>
+  g :: Int -> (forall b. Int -> b -> Int)
+</ProgramListing>
+but GHC "hoists" the <Literal>forall</Literal> to give the isomorphic type
+<ProgramListing>
+  g :: forall b. Int -> Int -> b -> Int
+</ProgramListing>
+In general, the rule is this: <Emphasis>to determine the type specified by any explicit
+user-written type (e.g. in a type signature), GHC expands type synonyms and then repeatedly
+performs the transformation:</Emphasis>
+<ProgramListing>
+  <Emphasis>type1</Emphasis> -> forall a. <Emphasis>type2</Emphasis>
+==>
+  forall a. <Emphasis>type1</Emphasis> -> <Emphasis>type2</Emphasis>
+</ProgramListing>
+(In fact, GHC tries to retain as much synonym information as possible for use in
+error messages, but that is a usability issue.)  This rule applies, of course, whether
+or not the <Literal>forall</Literal> comes from a synonym. For example, here is another
+valid way to write <Literal>g</Literal>'s type signature:
+<ProgramListing>
+  g :: Int -> Int -> forall b. b -> Int
+</ProgramListing>
+</Para>
+</Sect2>
+
 </Sect1>
 
 <Sect1 id="existential-quantification">
@@ -2092,14 +2714,14 @@ rank-2 types as applied to data constructors.
 The idea of using existential quantification in data type declarations
 was suggested by Laufer (I believe, thought doubtless someone will
 correct me), and implemented in Hope+. It's been in Lennart
-Augustsson's <Literal>hbc</Literal> Haskell compiler for several years, and
+Augustsson's <Command>hbc</Command> Haskell compiler for several years, and
 proved very useful.  Here's the idea.  Consider the declaration:
 </Para>
 
 <Para>
 
 <ProgramListing>
-  data Foo = forall a. MkFoo a (a -&#62; Bool)
+  data Foo = forall a. MkFoo a (a -> Bool)
            | Nil
 </ProgramListing>
 
@@ -2112,14 +2734,14 @@ The data type <Literal>Foo</Literal> has two constructors with types:
 <Para>
 
 <ProgramListing>
-  MkFoo :: forall a. a -&#62; (a -&#62; Bool) -&#62; Foo
+  MkFoo :: forall a. a -> (a -> Bool) -> Foo
   Nil   :: Foo
 </ProgramListing>
 
 </Para>
 
 <Para>
-Notice that the type variable <Literal>a</Literal> in the type of <Literal>MkFoo</Literal>
+Notice that the type variable <Literal>a</Literal> in the type of <Function>MkFoo</Function>
 does not appear in the data type itself, which is plain <Literal>Foo</Literal>.
 For example, the following expression is fine:
 </Para>
@@ -2134,14 +2756,14 @@ For example, the following expression is fine:
 
 <Para>
 Here, <Literal>(MkFoo 3 even)</Literal> packages an integer with a function
-<Literal>even</Literal> that maps an integer to <Literal>Bool</Literal>; and <Literal>MkFoo 'c'
-isUpper</Literal> packages a character with a compatible function.  These
+<Function>even</Function> that maps an integer to <Literal>Bool</Literal>; and <Function>MkFoo 'c'
+isUpper</Function> packages a character with a compatible function.  These
 two things are each of type <Literal>Foo</Literal> and can be put in a list.
 </Para>
 
 <Para>
 What can we do with a value of type <Literal>Foo</Literal>?.  In particular,
-what happens when we pattern-match on <Literal>MkFoo</Literal>?
+what happens when we pattern-match on <Function>MkFoo</Function>?
 </Para>
 
 <Para>
@@ -2153,15 +2775,15 @@ what happens when we pattern-match on <Literal>MkFoo</Literal>?
 </Para>
 
 <Para>
-Since all we know about <Literal>val</Literal> and <Literal>fn</Literal> is that they
+Since all we know about <Literal>val</Literal> and <Function>fn</Function> is that they
 are compatible, the only (useful) thing we can do with them is to
-apply <Literal>fn</Literal> to <Literal>val</Literal> to get a boolean.  For example:
+apply <Function>fn</Function> to <Literal>val</Literal> to get a boolean.  For example:
 </Para>
 
 <Para>
 
 <ProgramListing>
-  f :: Foo -&#62; Bool
+  f :: Foo -> Bool
   f (MkFoo val fn) = fn val
 </ProgramListing>
 
@@ -2180,13 +2802,13 @@ quite a bit of object-oriented-like programming this way.
 
 <Para>
 What has this to do with <Emphasis>existential</Emphasis> quantification?
-Simply that <Literal>MkFoo</Literal> has the (nearly) isomorphic type
+Simply that <Function>MkFoo</Function> has the (nearly) isomorphic type
 </Para>
 
 <Para>
 
 <ProgramListing>
-  MkFoo :: (exists a . (a, a -&#62; Bool)) -&#62; Foo
+  MkFoo :: (exists a . (a, a -> Bool)) -> Foo
 </ProgramListing>
 
 </Para>
@@ -2203,15 +2825,15 @@ adding a new existential quantification construct.
 <Title>Type classes</Title>
 
 <Para>
-An easy extension (implemented in <Literal>hbc</Literal>) is to allow
+An easy extension (implemented in <Command>hbc</Command>) is to allow
 arbitrary contexts before the constructor.  For example:
 </Para>
 
 <Para>
 
 <ProgramListing>
-  data Baz = forall a. Eq a =&#62; Baz1 a a
-           | forall b. Show b =&#62; Baz2 b (b -&#62; b)
+data Baz = forall a. Eq a => Baz1 a a
+         | forall b. Show b => Baz2 b (b -> b)
 </ProgramListing>
 
 </Para>
@@ -2223,15 +2845,15 @@ The two constructors have the types you'd expect:
 <Para>
 
 <ProgramListing>
-  Baz1 :: forall a. Eq a =&#62; a -&#62; a -&#62; Baz
-  Baz2 :: forall b. Show b =&#62; b -&#62; (b -&#62; b) -&#62; Baz
+Baz1 :: forall a. Eq a => a -> a -> Baz
+Baz2 :: forall b. Show b => b -> (b -> b) -> Baz
 </ProgramListing>
 
 </Para>
 
 <Para>
-But when pattern matching on <Literal>Baz1</Literal> the matched values can be compared
-for equality, and when pattern matching on <Literal>Baz2</Literal> the first matched
+But when pattern matching on <Function>Baz1</Function> the matched values can be compared
+for equality, and when pattern matching on <Function>Baz2</Function> the first matched
 value can be converted to a string (as well as applying the function to it).
 So this program is legal:
 </Para>
@@ -2239,7 +2861,7 @@ So this program is legal:
 <Para>
 
 <ProgramListing>
-  f :: Baz -&#62; String
+  f :: Baz -> String
   f (Baz1 p q) | p == q    = "Yes"
                | otherwise = "No"
   f (Baz1 v fn)            = show (fn v)
@@ -2249,7 +2871,7 @@ So this program is legal:
 
 <Para>
 Operationally, in a dictionary-passing implementation, the
-constructors <Literal>Baz1</Literal> and <Literal>Baz2</Literal> must store the
+constructors <Function>Baz1</Function> and <Function>Baz2</Function> must store the
 dictionaries for <Literal>Eq</Literal> and <Literal>Show</Literal> respectively, and
 extract it on pattern matching.
 </Para>
@@ -2282,17 +2904,17 @@ the pattern match.  For example, these fragments are incorrect:
 
 
 <ProgramListing>
-  f1 (MkFoo a f) = a
+f1 (MkFoo a f) = a
 </ProgramListing>
 
 
-Here, the type bound by <Literal>MkFoo</Literal> "escapes", because <Literal>a</Literal>
-is the result of <Literal>f1</Literal>.  One way to see why this is wrong is to
-ask what type <Literal>f1</Literal> has:
+Here, the type bound by <Function>MkFoo</Function> "escapes", because <Literal>a</Literal>
+is the result of <Function>f1</Function>.  One way to see why this is wrong is to
+ask what type <Function>f1</Function> has:
 
 
 <ProgramListing>
-  f1 :: Foo -&#62; a             -- Weird!
+  f1 :: Foo -> a             -- Weird!
 </ProgramListing>
 
 
@@ -2301,7 +2923,7 @@ this:
 
 
 <ProgramListing>
-  f1 :: forall a. Foo -&#62; a   -- Wrong!
+  f1 :: forall a. Foo -> a   -- Wrong!
 </ProgramListing>
 
 
@@ -2315,7 +2937,7 @@ The original program is just plain wrong.  Here's another sort of error
 
 It's ok to say <Literal>a==b</Literal> or <Literal>p==q</Literal>, but
 <Literal>a==q</Literal> is wrong because it equates the two distinct types arising
-from the two <Literal>Baz1</Literal> constructors.
+from the two <Function>Baz1</Function> constructors.
 
 
 </Para>
@@ -2355,7 +2977,7 @@ declarations.  So this is illegal:
 
 
 <ProgramListing>
-  newtype T = forall a. Ord a =&#62; MkT a
+  newtype T = forall a. Ord a => MkT a
 </ProgramListing>
 
 
@@ -2383,18 +3005,18 @@ data type with existentially quantified data constructors.
 Reason: in most cases it would not make sense. For example:&num;
 
 <ProgramListing>
-  data T = forall a. MkT [a] deriving( Eq )
+data T = forall a. MkT [a] deriving( Eq )
 </ProgramListing>
 
 To derive <Literal>Eq</Literal> in the standard way we would need to have equality
-between the single component of two <Literal>MkT</Literal> constructors:
+between the single component of two <Function>MkT</Function> constructors:
 
 <ProgramListing>
-  instance Eq T where
-    (MkT a) == (MkT b) = ???
+instance Eq T where
+  (MkT a) == (MkT b) = ???
 </ProgramListing>
 
-But <Literal>a</Literal> and <Literal>b</Literal> have distinct types, and so can't be compared.
+But <VarName>a</VarName> and <VarName>b</VarName> have distinct types, and so can't be compared.
 It's just about possible to imagine examples in which the derived instance
 would make sense, but it seems altogether simpler simply to prohibit such
 declarations.  Define your own instances!
@@ -2422,7 +3044,7 @@ could define a function like the following:
 <Para>
 
 <ProgramListing>
-assert :: Bool -&#62; a -&#62; a
+assert :: Bool -> a -> a
 assert False x = error "assertion failed!"
 assert _     x = x
 </ProgramListing>
@@ -2435,22 +3057,22 @@ an assertion failed, but which and where?
 </Para>
 
 <Para>
-One way out is to define an extended <Literal>assert</Literal> function which also
+One way out is to define an extended <Function>assert</Function> function which also
 takes a descriptive string to include in the error message and
 perhaps combine this with the use of a pre-processor which inserts
-the source location where <Literal>assert</Literal> was used.
+the source location where <Function>assert</Function> was used.
 </Para>
 
 <Para>
 Ghc offers a helping hand here, doing all of this for you. For every
-use of <Literal>assert</Literal> in the user's source:
+use of <Function>assert</Function> in the user's source:
 </Para>
 
 <Para>
 
 <ProgramListing>
-kelvinToC :: Double -&#62; Double
-kelvinToC k = assert (k &amp;gt;= 0.0) (k+273.15)
+kelvinToC :: Double -> Double
+kelvinToC k = assert (k &gt;= 0.0) (k+273.15)
 </ProgramListing>
 
 </Para>
@@ -2463,27 +3085,28 @@ assertion was made,
 <Para>
 
 <ProgramListing>
-assert pred val ==&#62; assertError "Main.hs|15" pred val
+assert pred val ==> assertError "Main.hs|15" pred val
 </ProgramListing>
 
 </Para>
 
 <Para>
 The rewrite is only performed by the compiler when it spots
-applications of <Literal>Exception.assert</Literal>, so you can still define and
-use your own versions of <Literal>assert</Literal>, should you so wish. If not,
-import <Literal>Exception</Literal> to make use <Literal>assert</Literal> in your code.
+applications of <Function>Exception.assert</Function>, so you can still define and
+use your own versions of <Function>assert</Function>, should you so wish. If not,
+import <Literal>Exception</Literal> to make use <Function>assert</Function> in your code.
 </Para>
 
 <Para>
 To have the compiler ignore uses of assert, use the compiler option
-<Literal>-fignore-asserts</Literal>. <IndexTerm><Primary>-fignore-asserts option</Primary></IndexTerm> That is,
+<Option>-fignore-asserts</Option>. <IndexTerm><Primary>-fignore-asserts option</Primary></IndexTerm> That is,
 expressions of the form <Literal>assert pred e</Literal> will be rewritten to <Literal>e</Literal>.
 </Para>
 
 <Para>
 Assertion failures can be caught, see the documentation for the
-Hugs/GHC Exception library for information of how.
+<literal>Exception</literal> library (<xref linkend="sec-Exception">)
+for the details.
 </Para>
 
 </Sect1>
@@ -2509,21 +3132,21 @@ f (xs::[a]) = ys ++ ys
 </Para>
 
 <Para>
-The pattern <Literal>(xs::[a])</Literal> includes a type signature for <Literal>xs</Literal>.
+The pattern <Literal>(xs::[a])</Literal> includes a type signature for <VarName>xs</VarName>.
 This brings the type variable <Literal>a</Literal> into scope; it scopes over
-all the patterns and right hand sides for this equation for <Literal>f</Literal>.
-In particular, it is in scope at the type signature for <Literal>y</Literal>.
+all the patterns and right hand sides for this equation for <Function>f</Function>.
+In particular, it is in scope at the type signature for <VarName>y</VarName>.
 </Para>
 
 <Para>
-At ordinary type signatures, such as that for <Literal>ys</Literal>, any type variables
+At ordinary type signatures, such as that for <VarName>ys</VarName>, any type variables
 mentioned in the type signature <Emphasis>that are not in scope</Emphasis> are
 implicitly universally quantified.  (If there are no type variables in
 scope, all type variables mentioned in the signature are universally
-quantified, which is just as in Haskell 98.)  In this case, since <Literal>a</Literal>
-is in scope, it is not universally quantified, so the type of <Literal>ys</Literal> is
-the same as that of <Literal>xs</Literal>.  In Haskell 98 it is not possible to declare
-a type for <Literal>ys</Literal>; a major benefit of scoped type variables is that
+quantified, which is just as in Haskell 98.)  In this case, since <VarName>a</VarName>
+is in scope, it is not universally quantified, so the type of <VarName>ys</VarName> is
+the same as that of <VarName>xs</VarName>.  In Haskell 98 it is not possible to declare
+a type for <VarName>ys</VarName>; a major benefit of scoped type variables is that
 it becomes possible to do so.
 </Para>
 
@@ -2578,12 +3201,12 @@ into scope (except in the type signature itself!). So this is illegal:
 
 
 <ProgramListing>
-  f :: a -&#62; a
+  f :: a -> a
   f x = x::a
 </ProgramListing>
 
 
-It's illegal because <Literal>a</Literal> is not in scope in the body of <Literal>f</Literal>,
+It's illegal because <VarName>a</VarName> is not in scope in the body of <Function>f</Function>,
 so the ordinary signature <Literal>x::a</Literal> is equivalent to <Literal>x::forall a.a</Literal>;
 and that is an incorrect typing.
 
@@ -2608,7 +3231,7 @@ scope over the methods defined in the <Literal>where</Literal> part.  For exampl
 
 <ProgramListing>
   class C a where
-    op :: [a] -&#62; a
+    op :: [a] -> a
 
     op xs = let ys::[a]
                 ys = reverse xs
@@ -2642,7 +3265,7 @@ no scoping associated with the names of the type variables in a separate type si
 
 
 <ProgramListing>
-   f :: [a] -&#62; [a]
+   f :: [a] -> [a]
    f (xs::[b]) = reverse xs
 </ProgramListing>
 
@@ -2695,7 +3318,7 @@ For example, the following all fail to type check:
   k (x::a) True    = ...        -- a unifies with Int
   k (x::Int) False = ...
 
-  w :: [b] -&#62; [b]
+  w :: [b] -> [b]
   w (x::a) = x                  -- a unifies with [b]
 </ProgramListing>
 
@@ -2742,15 +3365,15 @@ thus:
 </ProgramListing>
 
 
-The final <Literal>":: [a]"</Literal> after all the patterns gives a signature to the
+The final <Literal>:: [a]</Literal> after all the patterns gives a signature to the
 result type.  Sometimes this is the only way of naming the type variable
 you want:
 
 
 <ProgramListing>
-  f :: Int -&#62; [a] -&#62; [a]
-  f n :: ([a] -&#62; [a]) = let g (x::a, y::a) = (y,x)
-                        in \xs -&#62; map g (reverse xs `zip` xs)
+  f :: Int -> [a] -> [a]
+  f n :: ([a] -> [a]) = let g (x::a, y::a) = (y,x)
+                        in \xs -> map g (reverse xs `zip` xs)
 </ProgramListing>
 
 
@@ -2795,7 +3418,7 @@ in lambda abstractions:
 
 
 <ProgramListing>
-  (\ (x::a, y) :: a -&#62; x)
+  (\ (x::a, y) :: a -> x)
 </ProgramListing>
 
 
@@ -2806,13 +3429,13 @@ For example:
 
 <ProgramListing>
   f1 (x::c) = f1 x      -- ok
-  f2 = \(x::c) -&#62; f2 x  -- not ok
+  f2 = \(x::c) -> f2 x  -- not ok
 </ProgramListing>
 
 
-Here, <Literal>f1</Literal> is OK, but <Literal>f2</Literal> is not, because <Literal>c</Literal> gets unified
+Here, <Function>f1</Function> is OK, but <Function>f2</Function> is not, because <VarName>c</VarName> gets unified
 with a type variable free in the environment, in this
-case, the type of <Literal>f2</Literal>, which is in the environment when
+case, the type of <Function>f2</Function>, which is in the environment when
 the lambda abstraction is checked.
 
 </Para>
@@ -2825,7 +3448,7 @@ in <Literal>case</Literal> expressions:
 
 
 <ProgramListing>
-  case e of { (x::a, y) :: a -&#62; x }
+  case e of { (x::a, y) :: a -> x }
 </ProgramListing>
 
 
@@ -2836,7 +3459,7 @@ Thus this is OK:
 
 
 <ProgramListing>
-  case (True,False) of { (x::a, y) -&#62; x }
+  case (True,False) of { (x::a, y) -> x }
 </ProgramListing>
 
 
@@ -2846,7 +3469,7 @@ also OK to say:
 
 
 <ProgramListing>
-  case (True,False) of { (x::Bool, y) -&#62; x }
+  case (True,False) of { (x::Bool, y) -> x }
 </ProgramListing>
 
 
@@ -2855,14 +3478,14 @@ also OK to say:
 <ListItem>
 
 <Para>
-To avoid ambiguity, the type after the ``<Literal>::</Literal>'' in a result
+To avoid ambiguity, the type after the &ldquo;<Literal>::</Literal>&rdquo; in a result
 pattern signature on a lambda or <Literal>case</Literal> must be atomic (i.e. a single
 token or a parenthesised type of some sort).  To see why,
 consider how one would parse this:
 
 
 <ProgramListing>
-  \ x :: a -&#62; b -&#62; x
+  \ x :: a -> b -> x
 </ProgramListing>
 
 
@@ -2896,7 +3519,7 @@ though it binds a type variable:
 
 
 <ProgramListing>
-  f :: (b-&#62;b) = \(x::b) -&#62; x
+  f :: (b->b) = \(x::b) -> x
 </ProgramListing>
 
 
@@ -2912,14 +3535,14 @@ restriction.  Thus:
 <Para>
 
 <ProgramListing>
-  g :: a -&#62; a -&#62; Bool = \x y. x==y
+  g :: a -> a -> Bool = \x y. x==y
 </ProgramListing>
 
 </Para>
 
 <Para>
-Here <Literal>g</Literal> has type <Literal>forall a. Eq a =&gt; a -&gt; a -&gt; Bool</Literal>, just as if
-<Literal>g</Literal> had a separate type signature.  Lacking a type signature, <Literal>g</Literal>
+Here <Function>g</Function> has type <Literal>forall a. Eq a =&gt; a -&gt; a -&gt; Bool</Literal>, just as if
+<Function>g</Function> had a separate type signature.  Lacking a type signature, <Function>g</Function>
 would get a monomorphic type.
 </Para>
 
@@ -2941,7 +3564,7 @@ For example:
 <ProgramListing>
   data T = forall a. MkT [a]
 
-  f :: T -&#62; T
+  f :: T -> T
   f (MkT [t::a]) = MkT t3
                  where
                    t3::[a] = [t,t,t]
@@ -2976,8 +3599,8 @@ but they might affect the efficiency of the generated code.
 <IndexTerm><Primary>pragma, INLINE</Primary></IndexTerm></Title>
 
 <Para>
-GHC (with <Literal>-O</Literal>, as always) tries to inline (or ``unfold'')
-functions/values that are ``small enough,'' thus avoiding the call
+GHC (with <Option>-O</Option>, as always) tries to inline (or &ldquo;unfold&rdquo;)
+functions/values that are &ldquo;small enough,&rdquo; thus avoiding the call
 overhead and possibly exposing other more-wonderful optimisations.
 </Para>
 
@@ -2987,7 +3610,7 @@ interface files.
 </Para>
 
 <Para>
-Normally, if GHC decides a function is ``too expensive'' to inline, it
+Normally, if GHC decides a function is &ldquo;too expensive&rdquo; to inline, it
 will not do so, nor will it export that unfolding for other modules to
 use.
 </Para>
@@ -2997,7 +3620,7 @@ The sledgehammer you can bring to bear is the
 <Literal>INLINE</Literal><IndexTerm><Primary>INLINE pragma</Primary></IndexTerm> pragma, used thusly:
 
 <ProgramListing>
-key_function :: Int -&#62; String -&#62; (Bool, Double)
+key_function :: Int -> String -> (Bool, Double)
 
 #ifdef __GLASGOW_HASKELL__
 {-# INLINE key_function #-}
@@ -3010,7 +3633,7 @@ to stick the code through HBC&mdash;it doesn't like <Literal>INLINE</Literal> pr
 
 <Para>
 The major effect of an <Literal>INLINE</Literal> pragma is to declare a function's
-``cost'' to be very low.  The normal unfolding machinery will then be
+&ldquo;cost&rdquo; to be very low.  The normal unfolding machinery will then be
 very keen to inline it.
 </Para>
 
@@ -3071,7 +3694,7 @@ types.  Thus, if you have an overloaded function:
 <Para>
 
 <ProgramListing>
-hammeredLookup :: Ord key =&#62; [(key, value)] -&#62; key -&#62; value
+hammeredLookup :: Ord key => [(key, value)] -> key -> value
 </ProgramListing>
 
 </Para>
@@ -3081,7 +3704,7 @@ If it is heavily used on lists with <Literal>Widget</Literal> keys, you could
 specialise it as follows:
 
 <ProgramListing>
-{-# SPECIALIZE hammeredLookup :: [(Widget, value)] -&#62; Widget -&#62; value #-}
+{-# SPECIALIZE hammeredLookup :: [(Widget, value)] -> Widget -> value #-}
 </ProgramListing>
 
 </Para>
@@ -3094,8 +3717,8 @@ the specialised value, by adding <Literal>= blah</Literal>, as in:
 {-# SPECIALIZE hammeredLookup :: ...as before... = blah #-}
 </ProgramListing>
 
-It's <Emphasis>Your Responsibility</Emphasis> to make sure that <Literal>blah</Literal> really
-behaves as a specialised version of <Literal>hammeredLookup</Literal>!!!
+It's <Emphasis>Your Responsibility</Emphasis> to make sure that <Function>blah</Function> really
+behaves as a specialised version of <Function>hammeredLookup</Function>!!!
 </Para>
 
 <Para>
@@ -3106,14 +3729,14 @@ NOTE: the <Literal>=blah</Literal> feature isn't implemented in GHC 4.xx.
 An example in which the <Literal>= blah</Literal> form will Win Big:
 
 <ProgramListing>
-toDouble :: Real a =&#62; a -&#62; Double
+toDouble :: Real a => a -> Double
 toDouble = fromRational . toRational
 
-{-# SPECIALIZE toDouble :: Int -&#62; Double = i2d #-}
+{-# SPECIALIZE toDouble :: Int -> Double = i2d #-}
 i2d (I# i) = D# (int2Double# i) -- uses Glasgow prim-op directly
 </ProgramListing>
 
-The <Literal>i2d</Literal> function is virtually one machine instruction; the
+The <Function>i2d</Function> function is virtually one machine instruction; the
 default conversion&mdash;via an intermediate <Literal>Rational</Literal>&mdash;is obscenely
 expensive by comparison.
 </Para>
@@ -3140,7 +3763,7 @@ signature could be put.
 Same idea, except for instance declarations.  For example:
 
 <ProgramListing>
-instance (Eq a) =&#62; Eq (Foo a) where { ... usual stuff ... }
+instance (Eq a) => Eq (Foo a) where { ... usual stuff ... }
 
 {-# SPECIALIZE instance Eq (Foo [(Int, Bar)] #-}
 </ProgramListing>
@@ -3174,7 +3797,7 @@ number and filename of the original code; for example
 </Para>
 
 <Para>
-if you'd generated the current file from something called <Literal>Foo.vhs</Literal>
+if you'd generated the current file from something called <Filename>Foo.vhs</Filename>
 and this line corresponds to line 42 in the original.  GHC will adjust
 its error messages to refer to the line/file named in the <Literal>LINE</Literal>
 pragma.
@@ -3248,8 +3871,8 @@ enclosing definitions.
 <ListItem>
 
 <Para>
- Each variable mentioned in a rule must either be in scope (e.g. <Literal>map</Literal>),
-or bound by the <Literal>forall</Literal> (e.g. <Literal>f</Literal>, <Literal>g</Literal>, <Literal>xs</Literal>).  The variables bound by
+ Each variable mentioned in a rule must either be in scope (e.g. <Function>map</Function>),
+or bound by the <Literal>forall</Literal> (e.g. <Function>f</Function>, <Function>g</Function>, <Function>xs</Function>).  The variables bound by
 the <Literal>forall</Literal> are called the <Emphasis>pattern</Emphasis> variables.  They are separated
 by spaces, just like in a type <Literal>forall</Literal>.
 </Para>
@@ -3262,26 +3885,26 @@ If the type of the pattern variable is polymorphic, it <Emphasis>must</Emphasis>
 For example, here is the <Literal>foldr/build</Literal> rule:
 
 <ProgramListing>
-  "fold/build"  forall k z (g::forall b. (a-&#62;b-&#62;b) -&#62; b -&#62; b) .
-                foldr k z (build g) = g k z
+"fold/build"  forall k z (g::forall b. (a->b->b) -> b -> b) .
+              foldr k z (build g) = g k z
 </ProgramListing>
 
-Since <Literal>g</Literal> has a polymorphic type, it must have a type signature.
+Since <Function>g</Function> has a polymorphic type, it must have a type signature.
 
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- The left hand side of a rule must consist of a top-level variable applied
+The left hand side of a rule must consist of a top-level variable applied
 to arbitrary expressions.  For example, this is <Emphasis>not</Emphasis> OK:
 
 <ProgramListing>
-  "wrong1"   forall e1 e2.  case True of { True -&#62; e1; False -&#62; e2 } = e1
-  "wrong2"   forall f.      f True = True
+"wrong1"   forall e1 e2.  case True of { True -> e1; False -> e2 } = e1
+"wrong2"   forall f.      f True = True
 </ProgramListing>
 
-In <Literal>"wrong1"</Literal>, the LHS is not an application; in <Literal>"wrong1"</Literal>, the LHS has a pattern variable
+In <Literal>"wrong1"</Literal>, the LHS is not an application; in <Literal>"wrong2"</Literal>, the LHS has a pattern variable
 in the head.
 </Para>
 </ListItem>
@@ -3315,12 +3938,11 @@ From a semantic point of view:
 <ListItem>
 
 <Para>
- Rules are only applied if you use the <Literal>-O</Literal> flag.
-
+Rules are only applied if you use the <Option>-O</Option> flag.
 </Para>
 </ListItem>
-<ListItem>
 
+<ListItem>
 <Para>
  Rules are regarded as left-to-right rewrite rules.
 When GHC finds an expression that is a substitution instance of the LHS
@@ -3398,8 +4020,8 @@ For example, consider:
 </ProgramListing>
 
 The expression <Literal>s (t xs)</Literal> does not match the rule <Literal>"map/map"</Literal>, but GHC
-will substitute for <Literal>s</Literal> and <Literal>t</Literal>, giving an expression which does match.
-If <Literal>s</Literal> or <Literal>t</Literal> was (a) used more than once, and (b) large or a redex, then it would
+will substitute for <VarName>s</VarName> and <VarName>t</VarName>, giving an expression which does match.
+If <VarName>s</VarName> or <VarName>t</VarName> was (a) used more than once, and (b) large or a redex, then it would
 not be substituted, and the rule would not fire.
 
 </Para>
@@ -3421,20 +4043,20 @@ It will only match something written with explicit use of ".".
 Well, not quite.  It <Emphasis>will</Emphasis> match the expression
 
 <ProgramListing>
-        wibble f g xs
+wibble f g xs
 </ProgramListing>
 
-where <Literal>wibble</Literal> is defined:
+where <Function>wibble</Function> is defined:
 
 <ProgramListing>
-        wibble f g = map f . map g
+wibble f g = map f . map g
 </ProgramListing>
 
-because <Literal>wibble</Literal> will be inlined (it's small).
+because <Function>wibble</Function> will be inlined (it's small).
 
 Later on in compilation, GHC starts inlining even things on the
 LHS of rules, but still leaves the rules enabled.  This inlining
-policy is controlled by the per-simplification-pass flag <Literal>-finline-phase</Literal>n.
+policy is controlled by the per-simplification-pass flag <Option>-finline-phase</Option><Emphasis>n</Emphasis>.
 
 </Para>
 </ListItem>
@@ -3495,31 +4117,31 @@ The following are good producers:
 <ListItem>
 
 <Para>
- <Literal>++</Literal>
+ <Function>++</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>map</Literal>
+ <Function>map</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>filter</Literal>
+ <Function>filter</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>iterate</Literal>, <Literal>repeat</Literal>
+ <Function>iterate</Function>, <Function>repeat</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>zip</Literal>, <Literal>zipWith</Literal>
+ <Function>zip</Function>, <Function>zipWith</Function>
 </Para>
 </ListItem>
 
@@ -3540,86 +4162,86 @@ The following are good consumers:
 <ListItem>
 
 <Para>
- <Literal>array</Literal> (on its second argument)
+ <Function>array</Function> (on its second argument)
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>length</Literal>
+ <Function>length</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>++</Literal> (on its first argument)
+ <Function>++</Function> (on its first argument)
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>map</Literal>
+ <Function>map</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>filter</Literal>
+ <Function>filter</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>concat</Literal>
+ <Function>concat</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>unzip</Literal>, <Literal>unzip2</Literal>, <Literal>unzip3</Literal>, <Literal>unzip4</Literal>
+ <Function>unzip</Function>, <Function>unzip2</Function>, <Function>unzip3</Function>, <Function>unzip4</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>zip</Literal>, <Literal>zipWith</Literal> (but on one argument only; if both are good producers, <Literal>zip</Literal>
+ <Function>zip</Function>, <Function>zipWith</Function> (but on one argument only; if both are good producers, <Function>zip</Function>
 will fuse with one but not the other)
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>partition</Literal>
+ <Function>partition</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>head</Literal>
+ <Function>head</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>and</Literal>, <Literal>or</Literal>, <Literal>any</Literal>, <Literal>all</Literal>
+ <Function>and</Function>, <Function>or</Function>, <Function>any</Function>, <Function>all</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>sequence&lowbar;</Literal>
+ <Function>sequence&lowbar;</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>msum</Literal>
+ <Function>msum</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>sortBy</Literal>
+ <Function>sortBy</Function>
 </Para>
 </ListItem>
 
@@ -3631,7 +4253,7 @@ will fuse with one but not the other)
 So, for example, the following should generate no intermediate lists:
 
 <ProgramListing>
-        array (1,10) [(i,i*i) | i &#60;- map (+ 1) [0..9]]
+array (1,10) [(i,i*i) | i &#60;- map (+ 1) [0..9]]
 </ProgramListing>
 
 </Para>
@@ -3657,13 +4279,13 @@ Rewrite rules can be used to get the same effect as a feature
 present in earlier version of GHC:
 
 <ProgramListing>
-  {-# SPECIALIZE fromIntegral :: Int8 -&#62; Int16 = int8ToInt16 #-}
+  {-# SPECIALIZE fromIntegral :: Int8 -> Int16 = int8ToInt16 #-}
 </ProgramListing>
 
-This told GHC to use <Literal>int8ToInt16</Literal> instead of <Literal>fromIntegral</Literal> whenever
+This told GHC to use <Function>int8ToInt16</Function> instead of <Function>fromIntegral</Function> whenever
 the latter was called with type <Literal>Int8 -&gt; Int16</Literal>.  That is, rather than
-specialising the original definition of <Literal>fromIntegral</Literal> the programmer is
-promising that it is safe to use <Literal>int8ToInt16</Literal> instead.
+specialising the original definition of <Function>fromIntegral</Function> the programmer is
+promising that it is safe to use <Function>int8ToInt16</Function> instead.
 </Para>
 
 <Para>
@@ -3671,18 +4293,18 @@ This feature is no longer in GHC.  But rewrite rules let you do the
 same thing:
 
 <ProgramListing>
-  {-# RULES
-    "fromIntegral/Int8/Int16" fromIntegral = int8ToInt16
-  #-}
+{-# RULES
+  "fromIntegral/Int8/Int16" fromIntegral = int8ToInt16
+#-}
 </ProgramListing>
 
-This slightly odd-looking rule instructs GHC to replace <Literal>fromIntegral</Literal>
-by <Literal>int8ToInt16</Literal> <Emphasis>whenever the types match</Emphasis>.  Speaking more operationally,
+This slightly odd-looking rule instructs GHC to replace <Function>fromIntegral</Function>
+by <Function>int8ToInt16</Function> <Emphasis>whenever the types match</Emphasis>.  Speaking more operationally,
 GHC adds the type and dictionary applications to get the typed rule
 
 <ProgramListing>
-        forall (d1::Integral Int8) (d2::Num Int16) .
-                fromIntegral Int8 Int16 d1 d2 = int8ToInt16
+forall (d1::Integral Int8) (d2::Num Int16) .
+        fromIntegral Int8 Int16 d1 d2 = int8ToInt16
 </ProgramListing>
 
 What is more,
@@ -3702,29 +4324,29 @@ have an original definition available to specialise).
 <ListItem>
 
 <Para>
- Use <Literal>-ddump-rules</Literal> to see what transformation rules GHC is using.
+ Use <Option>-ddump-rules</Option> to see what transformation rules GHC is using.
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- Use <Literal>-ddump-simpl-stats</Literal> to see what rules are being fired.
-If you add <Literal>-dppr-debug</Literal> you get a more detailed listing.
+ Use <Option>-ddump-simpl-stats</Option> to see what rules are being fired.
+If you add <Option>-dppr-debug</Option> you get a more detailed listing.
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- The defintion of (say) <Literal>build</Literal> in <Literal>PrelBase.lhs</Literal> looks llike this:
+ The defintion of (say) <Function>build</Function> in <FileName>PrelBase.lhs</FileName> looks llike this:
 
 <ProgramListing>
-        build   :: forall a. (forall b. (a -&#62; b -&#62; b) -&#62; b -&#62; b) -&#62; [a]
+        build   :: forall a. (forall b. (a -> b -> b) -> b -> b) -> [a]
         {-# INLINE build #-}
         build g = g (:) []
 </ProgramListing>
 
 Notice the <Literal>INLINE</Literal>!  That prevents <Literal>(:)</Literal> from being inlined when compiling
-<Literal>PrelBase</Literal>, so that an importing module will ``see'' the <Literal>(:)</Literal>, and can
+<Literal>PrelBase</Literal>, so that an importing module will &ldquo;see&rdquo; the <Literal>(:)</Literal>, and can
 match it on the LHS of a rule.  <Literal>INLINE</Literal> prevents any inlining happening
 in the RHS of the <Literal>INLINE</Literal> thing.  I regret the delicacy of this.
 
@@ -3733,16 +4355,273 @@ in the RHS of the <Literal>INLINE</Literal> thing.  I regret the delicacy of thi
 <ListItem>
 
 <Para>
- In <Literal>ghc/lib/std/PrelBase.lhs</Literal> look at the rules for <Literal>map</Literal> to
+ In <Filename>ghc/lib/std/PrelBase.lhs</Filename> look at the rules for <Function>map</Function> to
 see how to write rules that will do fusion and yet give an efficient
-program even if fusion doesn't happen.  More rules in <Literal>PrelList.lhs</Literal>.
+program even if fusion doesn't happen.  More rules in <Filename>PrelList.lhs</Filename>.
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+</Sect2>
+
+</Sect1>
+
+<Sect1 id="generic-classes">
+<Title>Generic classes</Title>
+
+<Para>
+The ideas behind this extension are described in detail in "Derivable type classes",
+Ralf Hinze and Simon Peyton Jones, Haskell Workshop, Montreal Sept 2000, pp94-105.
+An example will give the idea:
+</Para>
+
+<ProgramListing>
+  import Generics
+
+  class Bin a where
+    toBin   :: a -> [Int]
+    fromBin :: [Int] -> (a, [Int])
+  
+    toBin {| Unit |}    Unit     = []
+    toBin {| a :+: b |} (Inl x)   = 0 : toBin x
+    toBin {| a :+: b |} (Inr y)   = 1 : toBin y
+    toBin {| a :*: b |} (x :*: y) = toBin x ++ toBin y
+  
+    fromBin {| Unit |}    bs      = (Unit, bs)
+    fromBin {| a :+: b |} (0:bs)  = (Inl x, bs')    where (x,bs') = fromBin bs
+    fromBin {| a :+: b |} (1:bs)  = (Inr y, bs')    where (y,bs') = fromBin bs
+    fromBin {| a :*: b |} bs     = (x :*: y, bs'') where (x,bs' ) = fromBin bs
+                                                         (y,bs'') = fromBin bs'
+</ProgramListing>
+<Para>
+This class declaration explains how <Literal>toBin</Literal> and <Literal>fromBin</Literal>
+work for arbitrary data types.  They do so by giving cases for unit, product, and sum,
+which are defined thus in the library module <Literal>Generics</Literal>:
+</Para>
+<ProgramListing>
+  data Unit    = Unit
+  data a :+: b = Inl a | Inr b
+  data a :*: b = a :*: b
+</ProgramListing>
+<Para>
+Now you can make a data type into an instance of Bin like this:
+<ProgramListing>
+  instance (Bin a, Bin b) => Bin (a,b)
+  instance Bin a => Bin [a]
+</ProgramListing>
+That is, just leave off the "where" clasuse.  Of course, you can put in the
+where clause and over-ride whichever methods you please.
+</Para>
+
+    <Sect2>
+      <Title> Using generics </Title>
+      <Para>To use generics you need to</para>
+      <ItemizedList>
+       <ListItem>
+         <Para>Use the <Option>-fgenerics</Option> flag.</Para>
+       </ListItem>
+       <ListItem>
+         <Para>Import the module <Literal>Generics</Literal> from the
+          <Literal>lang</Literal> package.  This import brings into
+          scope the data types <Literal>Unit</Literal>,
+          <Literal>:*:</Literal>, and <Literal>:+:</Literal>.  (You
+          don't need this import if you don't mention these types
+          explicitly; for example, if you are simply giving instance
+          declarations.)</Para>
+       </ListItem>
+      </ItemizedList>
+    </Sect2>
+
+<Sect2> <Title> Changes wrt the paper </Title>
+<Para>
+Note that the type constructors <Literal>:+:</Literal> and <Literal>:*:</Literal> 
+can be written infix (indeed, you can now use
+any operator starting in a colon as an infix type constructor).  Also note that
+the type constructors are not exactly as in the paper (Unit instead of 1, etc).
+Finally, note that the syntax of the type patterns in the class declaration
+uses "<Literal>{|</Literal>" and "<Literal>{|</Literal>" brackets; curly braces
+alone would ambiguous when they appear on right hand sides (an extension we 
+anticipate wanting).
+</Para>
+</Sect2>
+
+<Sect2> <Title>Terminology and restrictions</Title>
+<Para>
+Terminology.  A "generic default method" in a class declaration
+is one that is defined using type patterns as above.
+A "polymorphic default method" is a default method defined as in Haskell 98.
+A "generic class declaration" is a class declaration with at least one
+generic default method.
+</Para>
+
+<Para>
+Restrictions:
+<ItemizedList>
+<ListItem>
+<Para>
+Alas, we do not yet implement the stuff about constructor names and 
+field labels.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+A generic class can have only one parameter; you can't have a generic
+multi-parameter class.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+A default method must be defined entirely using type patterns, or entirely
+without.  So this is illegal:
+<ProgramListing>
+  class Foo a where
+    op :: a -> (a, Bool)
+    op {| Unit |} Unit = (Unit, True)
+    op x               = (x,    False)
+</ProgramListing>
+However it is perfectly OK for some methods of a generic class to have 
+generic default methods and others to have polymorphic default methods.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+The type variable(s) in the type pattern for a generic method declaration
+scope over the right hand side.  So this is legal (note the use of the type variable ``p'' in a type signature on the right hand side:
+<ProgramListing>
+  class Foo a where
+    op :: a -> Bool
+    op {| p :*: q |} (x :*: y) = op (x :: p)
+    ...
+</ProgramListing>
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+The type patterns in a generic default method must take one of the forms:
+<ProgramListing>
+       a :+: b
+       a :*: b
+       Unit
+</ProgramListing>
+where "a" and "b" are type variables.  Furthermore, all the type patterns for
+a single type constructor (<Literal>:*:</Literal>, say) must be identical; they
+must use the same type variables.  So this is illegal:
+<ProgramListing>
+  class Foo a where
+    op :: a -> Bool
+    op {| a :+: b |} (Inl x) = True
+    op {| p :+: q |} (Inr y) = False
+</ProgramListing>
+The type patterns must be identical, even in equations for different methods of the class.
+So this too is illegal:
+<ProgramListing>
+  class Foo a where
+    op1 :: a -> Bool
+    op {| a :*: b |} (Inl x) = True
+
+    op2 :: a -> Bool
+    op {| p :*: q |} (Inr y) = False
+</ProgramListing>
+(The reason for this restriction is that we gather all the equations for a particular type consructor
+into a single generic instance declaration.)
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+A generic method declaration must give a case for each of the three type constructors.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+The type for a generic method can be built only from:
+  <ItemizedList>
+  <ListItem> <Para> Function arrows </Para> </ListItem>
+  <ListItem> <Para> Type variables </Para> </ListItem>
+  <ListItem> <Para> Tuples </Para> </ListItem>
+  <ListItem> <Para> Arbitrary types not involving type variables </Para> </ListItem>
+  </ItemizedList>
+Here are some example type signatures for generic methods:
+<ProgramListing>
+    op1 :: a -> Bool
+    op2 :: Bool -> (a,Bool)
+    op3 :: [Int] -> a -> a
+    op4 :: [a] -> Bool
+</ProgramListing>
+Here, op1, op2, op3 are OK, but op4 is rejected, because it has a type variable
+inside a list.  
+</Para>
+<Para>
+This restriction is an implementation restriction: we just havn't got around to
+implementing the necessary bidirectional maps over arbitrary type constructors.
+It would be relatively easy to add specific type constructors, such as Maybe and list,
+to the ones that are allowed.</para>
+</ListItem>
+
+<ListItem>
+<Para>
+In an instance declaration for a generic class, the idea is that the compiler
+will fill in the methods for you, based on the generic templates.  However it can only
+do so if
+  <ItemizedList>
+  <ListItem>
+  <Para>
+  The instance type is simple (a type constructor applied to type variables, as in Haskell 98).
+  </Para>
+  </ListItem>
+  <ListItem>
+  <Para>
+  No constructor of the instance type has unboxed fields.
+  </Para>
+  </ListItem>
+  </ItemizedList>
+(Of course, these things can only arise if you are already using GHC extensions.)
+However, you can still give an instance declarations for types which break these rules,
+provided you give explicit code to override any generic default methods.
 </Para>
 </ListItem>
 
 </ItemizedList>
+</Para>
 
+<Para>
+The option <Option>-ddump-deriv</Option> dumps incomprehensible stuff giving details of 
+what the compiler does with generic declarations.
 </Para>
 
 </Sect2>
 
+<Sect2> <Title> Another example </Title>
+<Para>
+Just to finish with, here's another example I rather like:
+<ProgramListing>
+  class Tag a where
+    nCons :: a -> Int
+    nCons {| Unit |}    _ = 1
+    nCons {| a :*: b |} _ = 1
+    nCons {| a :+: b |} _ = nCons (bot::a) + nCons (bot::b)
+  
+    tag :: a -> Int
+    tag {| Unit |}    _       = 1
+    tag {| a :*: b |} _       = 1   
+    tag {| a :+: b |} (Inl x) = tag x
+    tag {| a :+: b |} (Inr y) = nCons (bot::a) + tag y
+</ProgramListing>
+</Para>
+</Sect2>
 </Sect1>
+
+<!-- Emacs stuff:
+     ;;; Local Variables: ***
+     ;;; mode: sgml ***
+     ;;; sgml-parent-document: ("users_guide.sgml" "book" "chapter" "sect1") ***
+     ;;; End: ***
+ -->