[project @ 2001-02-15 17:33:53 by simonmar]
[ghc-hetmet.git] / ghc / docs / users_guide / glasgow_exts.sgml
index 3c5cb62..bedbc08 100644 (file)
@@ -12,9 +12,7 @@ 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
 performance because of the implementation costs of Haskell's
-“high-level” features—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!
+“high-level” features—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!
 </Para>
 
 <Para>
@@ -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 &ldquo;Haskellised
-veneer&rdquo; 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,1024 +295,1434 @@ veneer&rdquo; 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 &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>
-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> (i.e. 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 <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
+<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 &ldquo;standard&rdquo; counterpart&mdash;we saw a
-threefold speedup on one example.
+go a <Emphasis>lot</Emphasis> faster than its &ldquo;standard&rdquo;
+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.
-</Para>
+</sect2>
 
-</Sect1>
-
-<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 &ldquo;C calls&rdquo;.
+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 <Function>ST</Function> 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 &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.
+ 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 &ldquo;mutated.&rdquo;  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>&ldquo;Static&rdquo; (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 &ldquo;static&rdquo; 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>&ldquo;Stable&rdquo; 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 &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.
+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>&ldquo;Foreign objects&rdquo;:</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 &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;
+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 &ldquo;primitive
-array&rdquo; 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><Function>&lowbar;ccall&lowbar;</Function> and <Function>&lowbar;casm&lowbar;</Function>: 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 (&ldquo;stdin&rdquo;::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 <Function>fooH</Function> unbox all of its arguments, call the C
-function <Function>fooC</Function> 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 <Function>&lowbar;ccall&lowbar;</Function>s is when the C types don't quite
-match the Haskell compiler's ideas.  For this, the <Function>&lowbar;casm&lowbar;</Function> 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#
 
-oldGetEnv name
-  = _casm_ &ldquo;%r = getenv((char *) %0);&rdquo; name &#62;&#62;= \ litstring -&#62;
-    return (
-        if (litstring == nullAddr) then
-            Left ("Fail:oldGetEnv:"++name)
-        else
-            Right (unpackCString litstring)
-    )
+{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>
-The first literal-literal argument to a <Function>&lowbar;casm&lowbar;</Function> is like a <Function>printf</Function>
-format: <Literal>&percnt;r</Literal> is replaced with the &ldquo;result,&rdquo; <Literal>&percnt;0</Literal>&ndash;<Literal>&percnt;n-1</Literal> are
-replaced with the 1st&ndash;nth arguments.  As you can see above, it is an
-easy way to do simple C&nbsp;casting.  Everything said about <Function>&lowbar;ccall&lowbar;</Function> goes
-for <Function>&lowbar;casm&lowbar;</Function> as well.
+<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>
-The use of <Function>&lowbar;casm&lowbar;</Function> 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 <Function>&lowbar;casm&lowbar;</Function>, 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 <Function>&lowbar;casm&lowbar;</Function>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 <Function>&lowbar;casm&lowbar;</Function>, 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 <Function>&lowbar;casm&lowbar;</Function> 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.
+<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>
 
 <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
-<Option>-funfold-casms-in-hi-file</Option> will turn off the default behaviour.
-<IndexTerm><Primary>-funfold-casms-in-hi-file option</Primary></IndexTerm>
+And a full complement of trigonometric functions:
 </Para>
 
-</Sect2>
+<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>
 
-<Sect2 id="glasgow-literal-literals">
-<Title>Literal-literals</Title>
+<Para>
+similarly for <Literal>Float&num;</Literal>.
+</Para>
 
 <Para>
-<IndexTerm><Primary>Literal-literals</Primary></IndexTerm>
-The literal-literal argument to <Function>&lowbar;casm&lowbar;</Function> can be made use of separately
-from the <Function>&lowbar;casm&lowbar;</Function> construct itself. Indeed, we've already used it:
+There are two coercion functions for <Literal>Float&num;</Literal>/<Literal>Double&num;</Literal>:
 </Para>
 
 <Para>
 
 <ProgramListing>
-fooH :: Char -&#62; Int -&#62; Double -&#62; Word -&#62; IO Double
-fooH c i d w = _ccall_ fooC (&ldquo;stdin&rdquo;::Addr) c i d w
+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 first argument that's passed to <Function>fooC</Function> is given as a literal-literal,
-that is, a literal chunk of C code that will be inserted into the generated
-<Filename>.hc</Filename> code at the right place.
+The primitive version of <Function>decodeDouble</Function>
+(<Function>encodeDouble</Function> is implemented as an external C
+function):
 </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.
+
+<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>
-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.
+(And the same for <Literal>Float&num;</Literal>s.)
 </Para>
 
 </Sect2>
 
-<Sect2 id="glasgow-foreign-headers">
-<Title>Using function headers
+<Sect2 id="integer-operations">
+<Title>Operations on/for <Literal>Integers</Literal> (interface to GMP)
 </Title>
 
 <Para>
-<IndexTerm><Primary>C calls, function headers</Primary></IndexTerm>
+<IndexTerm><Primary>arbitrary precision integers</Primary></IndexTerm>
+<IndexTerm><Primary>Integer, operations on</Primary></IndexTerm>
 </Para>
 
 <Para>
-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.
+We implement <Literal>Integers</Literal> (arbitrary-precision
+integers) using the GNU multiple-precision (GMP) package (version
+2.0.2).
 </Para>
 
 <Para>
-For example,
+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>
+<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>
-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 <Command>gcc</Command> on your architecture by consulting
-<Filename>ghc/includes/StgTypes.h</Filename>.  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 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>
+
+<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>
+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>
+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-stablePtrs">
-<Title>Subverting automatic unboxing with &ldquo;stable pointers&rdquo;
-</Title>
+<Sect2>
+<Title>Arrays</Title>
 
 <Para>
-<IndexTerm><Primary>stable pointers (Glasgow extension)</Primary></IndexTerm>
+<IndexTerm><Primary>arrays, primitive</Primary></IndexTerm>
 </Para>
 
 <Para>
-The arguments of a <Function>&lowbar;ccall&lowbar;</Function> automatically unboxed before the
-call.  There are two reasons why this is usually the Right Thing to
-do:
+The type <Literal>Array&num; elt</Literal> is the type of primitive,
+unpointed arrays of values of type <Literal>elt</Literal>.
 </Para>
 
 <Para>
 
-<ItemizedList>
-<ListItem>
+<ProgramListing>
+type Array# elt
+</ProgramListing>
+
+<IndexTerm><Primary><literal>Array&num;</literal></Primary></IndexTerm>
+</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.
+<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>
-</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>.
+
+<ProgramListing>
+type ByteArray#
+</ProgramListing>
+
+<IndexTerm><Primary><literal>ByteArray&num;</literal></Primary></IndexTerm>
 </Para>
-</ListItem>
 
-</ItemizedList>
+<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>
+<Title>Reading and writing</Title>
+
+<Para>
+Primitive arrays are linear, and indexed starting at zero.
+</Para>
+
+<Para>
+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>
 
 <Para>
-It is possible to subvert the unboxing process by creating a &ldquo;stable
-pointer&rdquo; to a value and passing the stable pointer instead.  For
-example, to pass/return an integer lazily to C functions <Function>storeC</Function> and
-<Function>fetchC</Function> might write:
+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>
+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>
-storeH :: Int -&#62; IO ()
-storeH x = makeStablePtr x              &#62;&#62;= \ stable_x -&#62;
-           _ccall_ storeC stable_x
+indexCharArray#   :: ByteArray# -> Int# -> Char#
+indexIntArray#    :: ByteArray# -> Int# -> Int#
+indexAddrArray#   :: ByteArray# -> Int# -> Addr#
+indexFloatArray#  :: ByteArray# -> Int# -> Float#
+indexDoubleArray# :: ByteArray# -> Int# -> Double#
 
-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
+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>
+
+<Para>
+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>
 
 <Para>
-The garbage collector will refrain from throwing a stable pointer away
-until you explicitly call one of the following from C or Haskell.
+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>
-void freeStablePointer( StgStablePtr stablePtrToToss )
-freeStablePtr :: StablePtr a -&#62; IO ()
+indexArray#       :: Array# elt -> Int# -> (# elt #)
 </ProgramListing>
 
+<IndexTerm><Primary><literal>indexArray&num;</literal></Primary></IndexTerm>
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>The state type</Title>
+
+<Para>
+<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>
-As with the use of <Function>free</Function> 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.
+
+<ProgramListing>
+type State# s
+</ProgramListing>
+
 </Para>
 
 <Para>
-And to force evaluation of the argument within <Function>fooC</Function>, one would
-call one of the following C functions (according to type of argument).
+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>
 
 <ProgramListing>
-void     performIO  ( StgStablePtr stableIndex /* StablePtr s (IO ()) */ );
-StgInt   enterInt   ( StgStablePtr stableIndex /* StablePtr s Int */ );
-StgFloat enterFloat ( StgStablePtr stableIndex /* StablePtr s Float */ );
+data RealWorld
 </ProgramListing>
 
 </Para>
 
+</Sect2>
+
+<Sect2>
+<Title>State of the world</Title>
+
+<Para>
+A single, primitive, value of type <Literal>State&num; RealWorld</Literal> is provided.
+</Para>
+
 <Para>
-<IndexTerm><Primary>performIO</Primary></IndexTerm>
-<IndexTerm><Primary>enterInt</Primary></IndexTerm>
-<IndexTerm><Primary>enterFloat</Primary></IndexTerm>
+
+<ProgramListing>
+realWorld# :: State# RealWorld
+</ProgramListing>
+
+<IndexTerm><Primary>realWorld&num; state object</Primary></IndexTerm>
 </Para>
 
 <Para>
-Nota Bene: <Function>&lowbar;ccall&lowbar;GC&lowbar;</Function><IndexTerm><Primary>&lowbar;ccall&lowbar;GC&lowbar;</Primary></IndexTerm> must be used if any of
-these functions are used.
+(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="glasgow-foreignObjs">
-<Title>Foreign objects: pointing outside the Haskell heap
-</Title>
+<Sect2 id="sect-mutable">
+<Title>Mutable arrays</Title>
+
+<Para>
+<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>
+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>mutable arrays, allocation</Primary></IndexTerm>
+<IndexTerm><Primary>arrays, allocation</Primary></IndexTerm>
+<IndexTerm><Primary>allocation, of mutable arrays</Primary></IndexTerm>
+</Para>
+
+<Para>
+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>
+
+<Para>
+
+<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>
+The size of a <Literal>ByteArray&num;</Literal> is given in bytes.
+</Para>
+
+</Sect3>
+
+<Sect3>
+<Title>Reading and writing</Title>
 
 <Para>
-<IndexTerm><Primary>foreign objects (Glasgow extension)</Primary></IndexTerm>
+<IndexTerm><Primary>arrays, reading and writing</Primary></IndexTerm>
 </Para>
 
 <Para>
-There are two types that GHC programs can use to reference
-(heap-allocated) objects outside the Haskell world: <Literal>Addr</Literal> and
-<Literal>ForeignObj</Literal>.
+
+<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>Addr</Literal>, it is up to you to the programmer to arrange
-allocation and deallocation of the objects.
+<IndexTerm><Primary>arrays, testing for equality</Primary></IndexTerm>
 </Para>
 
 <Para>
-If you use <Literal>ForeignObj</Literal>, GHC'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:
+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>
+
+<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>
+
+</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>
-More information on the programmers' interface to <Literal>ForeignObj</Literal> can be
-found in the library documentation.
+The <Literal>ST</Literal> library, which provides access to the
+<Function>ST</Function> monad, is described in <xref
+linkend="sec-ST">.
 </Para>
 
-</Sect2>
+</Sect1>
 
-<Sect2 id="glasgow-avoiding-monads">
-<Title>Avoiding monads
+<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 <Function>&lowbar;ccall&lowbar;</Function> 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
-<Function>printf</Function>.  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 <Function>unsafePerformIO</Function>, 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_ &ldquo;sincosd( %0, &amp;((double *)%1[0]), &amp;((double *)%1[1]) );&rdquo; 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 <Function>trace</Function> 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 = (&ldquo;stderr&rdquo; :: 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 &ldquo;gotchas&rdquo; 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 <Function>&lowbar;ccall&lowbar;</Function>s, etc., compile with
-<Option>-fvia-C</Option>.<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 <Option>-&num;include "prototypes.h"</Option> 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 <Function>&lowbar;ccall&lowbar;</Function>s.  (It shouldn't be that way, but&hellip;).
-GHC will pass the flag <Option>-Wimplicit</Option> to <Command>gcc</Command> so that you'll get warnings
-if any <Function>&lowbar;ccall&lowbar;</Function>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 <Function>&lowbar;ccall&lowbar;</Function>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 <Option>-keep-hc-file-too</Option> and look at
-the intermediate C (<Function>.hc</Function>).
+<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 <Function>&lowbar;ccall&lowbar;</Function>: the arguments
-(respectively result) of <Function>&lowbar;ccall&lowbar;</Function> 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 <VarName>x</VarName>
-is, nor what type the <Function>&lowbar;ccall&lowbar;</Function> 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 <Function>&lowbar;ccall&lowbar;GC&lowbar;</Function><IndexTerm><Primary>&lowbar;ccall&lowbar;GC&lowbar; primitive</Primary></IndexTerm> or
-<Function>&lowbar;casm&lowbar;GC&lowbar;</Function><IndexTerm><Primary>&lowbar;casm&lowbar;GC&lowbar; primitive</Primary></IndexTerm> variant of C-calls.  (This
-does not work with the native code generator&mdash;use <Option>-fvia-C</Option>.) 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>
@@ -1152,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>
@@ -1186,7 +1765,7 @@ type:
 <Para>
 
 <ProgramListing>
-  forall tv1..tvn (c1, ...,cn) =&#62; type
+  forall tv1..tvn (c1, ...,cn) => type
 </ProgramListing>
 
 </Para>
@@ -1214,7 +1793,7 @@ ambiguity. Here, for example, is an illegal type:
 
 
 <ProgramListing>
-  forall a. Eq a =&#62; Int
+  forall a. Eq a => Int
 </ProgramListing>
 
 
@@ -1238,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>
 
 
@@ -1247,7 +1826,7 @@ mention <Literal>a</Literal>:
 
 
 <ProgramListing>
-  forall a. Eq b =&#62; burble
+  forall a. Eq b => burble
 </ProgramListing>
 
 
@@ -1279,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>
@@ -1305,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>
 
@@ -1323,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>
 
 
@@ -1345,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>
 
 
@@ -1367,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>
 
 
@@ -1378,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>
 
 
@@ -1389,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>
 
 
@@ -1410,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>
 
 
@@ -1425,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>
 
 
@@ -1439,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>
 
 
@@ -1453,7 +2032,7 @@ class like this:
 
 </Sect2>
 
-<Sect2>
+<Sect2 id="instance-decls">
 <Title>Instance declarations</Title>
 
 <Para>
@@ -1467,8 +2046,8 @@ 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>
 
 
@@ -1544,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:
 
 
@@ -1573,7 +2152,7 @@ loop if it wasn't excluded:
 
 
 <ProgramListing>
-  instance C a =&#62; C a where ...
+  instance C a => C a where ...
 </ProgramListing>
 
 
@@ -1594,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>
 
 
@@ -1604,7 +2183,7 @@ This allows you to write shorter signatures:
 
 
 <ProgramListing>
-  f :: C a =&#62; ...
+  f :: C a => ...
 </ProgramListing>
 
 
@@ -1612,7 +2191,7 @@ instead of
 
 
 <ProgramListing>
-  f :: (C1 a, C2 a, C3 a) =&#62; ...
+  f :: (C1 a, C2 a, C3 a) => ...
 </ProgramListing>
 
 
@@ -1671,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>
 
 
@@ -1679,7 +2258,7 @@ is OK, but
 
 
 <ProgramListing>
-instance C Int b =&#62; Foo b where ...
+instance C Int b => Foo b where ...
 </ProgramListing>
 
 
@@ -1717,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>
@@ -1735,7 +2314,7 @@ allows us to say exactly what this means.  For example:
 <Para>
 
 <ProgramListing>
-        g :: b -&#62; b
+        g :: b -> b
 </ProgramListing>
 
 </Para>
@@ -1747,7 +2326,7 @@ means this:
 <Para>
 
 <ProgramListing>
-        g :: forall b. (b -&#62; b)
+        g :: forall b. (b -> b)
 </ProgramListing>
 
 </Para>
@@ -1768,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>
@@ -1787,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; T 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>
@@ -1810,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
@@ -1838,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>
@@ -1872,16 +2451,16 @@ 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>
 
@@ -1901,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>
 
@@ -1913,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
@@ -1950,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>
@@ -1958,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 <Function>T1</Function>, because
-the sub-expression <Literal>T1 (\a b -&#62; a)</Literal> has type <Literal>Int -&#62; T
+the sub-expression <Literal>T1 (\a b -> a)</Literal> has type <Literal>Int -> T
 Int</Literal>.
 </Para>
 
@@ -2010,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>
 
@@ -2018,7 +2597,7 @@ 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
+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>
@@ -2038,8 +2617,8 @@ grammar:
 
 
 <ProgramListing>
-rank2type ::= [forall tyvars .] [context =&#62;] funty
-funty     ::= ([forall tyvars .] [context =&#62;] ty) -&#62; funty
+rank2type ::= [forall tyvars .] [context =>] funty
+funty     ::= ([forall tyvars .] [context =>] ty) -> funty
             | ty
 ty        ::= ...current Haskell monotype syntax...
 </ProgramListing>
@@ -2060,8 +2639,8 @@ 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>
 
 
@@ -2142,7 +2721,7 @@ proved very useful.  Here's the idea.  Consider the declaration:
 <Para>
 
 <ProgramListing>
-  data Foo = forall a. MkFoo a (a -&#62; Bool)
+  data Foo = forall a. MkFoo a (a -> Bool)
            | Nil
 </ProgramListing>
 
@@ -2155,7 +2734,7 @@ 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>
 
@@ -2204,7 +2783,7 @@ apply <Function>fn</Function> to <Literal>val</Literal> to get a boolean.  For e
 <Para>
 
 <ProgramListing>
-  f :: Foo -&#62; Bool
+  f :: Foo -> Bool
   f (MkFoo val fn) = fn val
 </ProgramListing>
 
@@ -2229,7 +2808,7 @@ Simply that <Function>MkFoo</Function> has the (nearly) isomorphic type
 <Para>
 
 <ProgramListing>
-  MkFoo :: (exists a . (a, a -&#62; Bool)) -&#62; Foo
+  MkFoo :: (exists a . (a, a -> Bool)) -> Foo
 </ProgramListing>
 
 </Para>
@@ -2253,8 +2832,8 @@ arbitrary contexts before the constructor.  For example:
 <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>
@@ -2266,8 +2845,8 @@ 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>
@@ -2282,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)
@@ -2335,7 +2914,7 @@ ask what type <Function>f1</Function> has:
 
 
 <ProgramListing>
-  f1 :: Foo -&#62; a             -- Weird!
+  f1 :: Foo -> a             -- Weird!
 </ProgramListing>
 
 
@@ -2344,7 +2923,7 @@ this:
 
 
 <ProgramListing>
-  f1 :: forall a. Foo -&#62; a   -- Wrong!
+  f1 :: forall a. Foo -> a   -- Wrong!
 </ProgramListing>
 
 
@@ -2398,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>
 
 
@@ -2465,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>
@@ -2492,8 +3071,8 @@ use of <Function>assert</Function> in the user's source:
 <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>
@@ -2506,7 +3085,7 @@ 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>
@@ -2526,7 +3105,8 @@ expressions of the form <Literal>assert pred e</Literal> will be rewritten to <L
 
 <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>
@@ -2621,7 +3201,7 @@ 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>
 
@@ -2651,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
@@ -2685,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>
 
@@ -2738,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>
 
@@ -2791,9 +3371,9 @@ 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>
 
 
@@ -2838,7 +3418,7 @@ in lambda abstractions:
 
 
 <ProgramListing>
-  (\ (x::a, y) :: a -&#62; x)
+  (\ (x::a, y) :: a -> x)
 </ProgramListing>
 
 
@@ -2849,7 +3429,7 @@ 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>
 
 
@@ -2868,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>
 
 
@@ -2879,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>
 
 
@@ -2889,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>
 
 
@@ -2905,7 +3485,7 @@ consider how one would parse this:
 
 
 <ProgramListing>
-  \ x :: a -&#62; b -&#62; x
+  \ x :: a -> b -> x
 </ProgramListing>
 
 
@@ -2939,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>
 
 
@@ -2955,7 +3535,7 @@ restriction.  Thus:
 <Para>
 
 <ProgramListing>
-  g :: a -&#62; a -&#62; Bool = \x y. x==y
+  g :: a -> a -> Bool = \x y. x==y
 </ProgramListing>
 
 </Para>
@@ -2984,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]
@@ -3040,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 #-}
@@ -3114,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>
@@ -3124,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>
@@ -3149,10 +3729,10 @@ 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>
 
@@ -3183,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>
@@ -3305,7 +3885,7 @@ 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) .
+"fold/build"  forall k z (g::forall b. (a->b->b) -> b -> b) .
               foldr k z (build g) = g k z
 </ProgramListing>
 
@@ -3320,11 +3900,11 @@ 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
+"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>
@@ -3699,7 +4279,7 @@ 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 <Function>int8ToInt16</Function> instead of <Function>fromIntegral</Function> whenever
@@ -3760,7 +4340,7 @@ If you add <Option>-dppr-debug</Option> you get a more detailed listing.
  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>
@@ -3788,3 +4368,260 @@ program even if fusion doesn't happen.  More rules in <Filename>PrelList.lhs</Fi
 </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: ***
+ -->