[project @ 2000-07-20 10:50:47 by rrt]
[ghc-hetmet.git] / ghc / docs / users_guide / glasgow_exts.sgml
index c7d50be..c962f87 100644 (file)
@@ -2,7 +2,7 @@
 <IndexTerm><Primary>language, GHC</Primary></IndexTerm>
 <IndexTerm><Primary>extensions, GHC</Primary></IndexTerm>
 As with all known Haskell systems, GHC implements some extensions to
-the language.  To use them, you'll need to give a <Literal>-fglasgow-exts</Literal>
+the language.  To use them, you'll need to give a <Option>-fglasgow-exts</Option>
 <IndexTerm><Primary>-fglasgow-exts option</Primary></IndexTerm> option.
 </Para>
 
@@ -10,11 +10,9 @@ the language.  To use them, you'll need to give a <Literal>-fglasgow-exts</Liter
 Virtually all of the Glasgow extensions serve to give you access to
 the underlying facilities with which we implement Haskell.  Thus, you
 can get at the Raw Iron, if you are willing to write some non-standard
-code at a more primitive level.  You need not be ``stuck'' on
+code at a more primitive level.  You need not be &ldquo;stuck&rdquo; on
 performance because of the implementation costs of Haskell's
-``high-level'' features&mdash;you can always code ``under'' them.  In an
-extreme case, you can write all your time-critical code in C, and then
-just glue it together with Haskell!
+&ldquo;high-level&rdquo; features&mdash;you can always code &ldquo;under&rdquo; them.  In an extreme case, you can write all your time-critical code in C, and then just glue it together with Haskell!
 </Para>
 
 <Para>
@@ -29,7 +27,7 @@ Executive summary of our extensions:
 <ListItem>
 <Para>
 You can get right down to the raw machine types and operations;
-included in this are ``primitive arrays'' (direct access to Big Wads
+included in this are &ldquo;primitive arrays&rdquo; (direct access to Big Wads
 of Bytes).  Please see <XRef LinkEnd="glasgow-unboxed"> and following.
 </Para>
 </ListItem>
@@ -78,11 +76,20 @@ for some nested declarations, where this would not be legal in Haskell
 </VarListEntry>
 
 <VarListEntry>
-<Term>Calling out to C:</Term>
+<Term>Pattern guards</Term>
+<ListItem>
+<Para>
+Instead of being a boolean expression, a guard is a list of qualifiers, exactly as in a list comprehension. See <XRef LinkEnd="pattern-guards">.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term>Foreign calling:</Term>
 <ListItem>
 <Para>
 Just what it sounds like.  We provide <Emphasis>lots</Emphasis> of rope that you
-can dangle around your neck.  Please see <XRef LinkEnd="glasgow-ccalls">.
+can dangle around your neck.  Please see <XRef LinkEnd="ffi">.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -112,1041 +119,1461 @@ Details in <XRef LinkEnd="rewrite-rules">.
 
 <Para>
 Before you get too carried away working at the lowest level (e.g.,
-sloshing <Literal>MutableByteArray&num;</Literal>s around your program), you may wish to
-check if there are system libraries that provide a ``Haskellised
-veneer'' over the features you want.  See <XRef LinkEnd="ghc-prelude">.
+sloshing <Literal>MutableByteArray&num;</Literal>s around your
+program), you may wish to check if there are libraries that provide a
+&ldquo;Haskellised veneer&rdquo; over the features you want.  See
+<xref linkend="book-hslibs">.
 </Para>
 
-<Sect1 id="glasgow-unboxed">
-<Title>Unboxed types
+<Sect1 id="primitives">
+<Title>Unboxed types and primitive operations
 </Title>
+<IndexTerm><Primary>PrelGHC module</Primary></IndexTerm>
 
 <Para>
-<IndexTerm><Primary>Unboxed types (Glasgow extension)</Primary></IndexTerm>
+This module defines all the types which are primitive in Glasgow
+Haskell, and the operations provided for them.
 </Para>
 
+<Sect2 id="glasgow-unboxed">
+<Title>Unboxed types
+</Title>
+
 <Para>
-These types correspond to the ``raw machine'' types you would use in
-C: <Literal>Int&num;</Literal> (long int), <Literal>Double&num;</Literal> (double), <Literal>Addr&num;</Literal> (void *), etc.  The
-<Emphasis>primitive operations</Emphasis> (PrimOps) on these types are what you
-might expect; e.g., <Literal>(+&num;)</Literal> is addition on <Literal>Int&num;</Literal>s, and is the
-machine-addition that we all know and love&mdash;usually one instruction.
+<IndexTerm><Primary>Unboxed types (Glasgow extension)</Primary></IndexTerm>
 </Para>
 
-<Para>
-There are some restrictions on the use of unboxed types, the main one
-being that you can't pass an unboxed value to a polymorphic function
-or store one in a polymorphic data type.  This rules out things like
-<Literal>[Int&num;]</Literal> (ie. lists of unboxed integers).  The reason for this
-restriction is that polymorphic arguments and constructor fields are
-assumed to be pointers: if an unboxed integer is stored in one of
-these, the garbage collector would attempt to follow it, leading to
-unpredictable space leaks.  Or a <Literal>seq</Literal> operation on the polymorphic
-component may attempt to dereference the pointer, with disastrous
-results.  Even worse, the unboxed value might be larger than a pointer
+<para>Most types in GHC are <firstterm>boxed</firstterm>, which means
+that values of that type are represented by a pointer to a heap
+object.  The representation of a Haskell <literal>Int</literal>, for
+example, is a two-word heap object.  An <firstterm>unboxed</firstterm>
+type, however, is represented by the value itself, no pointers or heap
+allocation are involved.
+</para>
+
+<Para>
+Unboxed types correspond to the &ldquo;raw machine&rdquo; types you
+would use in C: <Literal>Int&num;</Literal> (long int),
+<Literal>Double&num;</Literal> (double), <Literal>Addr&num;</Literal>
+(void *), etc.  The <Emphasis>primitive operations</Emphasis>
+(PrimOps) on these types are what you might expect; e.g.,
+<Literal>(+&num;)</Literal> is addition on
+<Literal>Int&num;</Literal>s, and is the machine-addition that we all
+know and love&mdash;usually one instruction.
+</Para>
+
+<Para>
+Primitive (unboxed) types cannot be defined in Haskell, and are
+therefore built into the language and compiler.  Primitive types are
+always unlifted; that is, a value of a primitive type cannot be
+bottom.  We use the convention that primitive types, values, and
+operations have a <Literal>&num;</Literal> suffix.
+</Para>
+
+<Para>
+Primitive values are often represented by a simple bit-pattern, such
+as <Literal>Int&num;</Literal>, <Literal>Float&num;</Literal>,
+<Literal>Double&num;</Literal>.  But this is not necessarily the case:
+a primitive value might be represented by a pointer to a
+heap-allocated object.  Examples include
+<Literal>Array&num;</Literal>, the type of primitive arrays.  A
+primitive array is heap-allocated because it is too big a value to fit
+in a register, and would be too expensive to copy around; in a sense,
+it is accidental that it is represented by a pointer.  If a pointer
+represents a primitive value, then it really does point to that value:
+no unevaluated thunks, no indirections&hellip;nothing can be at the
+other end of the pointer than the primitive value.
+</Para>
+
+<Para>
+There are some restrictions on the use of primitive types, the main
+one being that you can't pass a primitive value to a polymorphic
+function or store one in a polymorphic data type.  This rules out
+things like <Literal>[Int&num;]</Literal> (i.e. lists of primitive
+integers).  The reason for this restriction is that polymorphic
+arguments and constructor fields are assumed to be pointers: if an
+unboxed integer is stored in one of these, the garbage collector would
+attempt to follow it, leading to unpredictable space leaks.  Or a
+<Function>seq</Function> operation on the polymorphic component may
+attempt to dereference the pointer, with disastrous results.  Even
+worse, the unboxed value might be larger than a pointer
 (<Literal>Double&num;</Literal> for instance).
 </Para>
 
 <Para>
 Nevertheless, A numerically-intensive program using unboxed types can
-go a <Emphasis>lot</Emphasis> faster than its ``standard'' counterpart&mdash;we saw a
-threefold speedup on one example.
+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>
-
-</Sect1>
+</sect2>
 
-<Sect1 id="glasgow-ST-monad">
-<Title>Primitive state-transformer monad
+<Sect2 id="unboxed-tuples">
+<Title>Unboxed Tuples
 </Title>
 
 <Para>
-<IndexTerm><Primary>state transformers (Glasgow extensions)</Primary></IndexTerm>
-<IndexTerm><Primary>ST monad (Glasgow extension)</Primary></IndexTerm>
-</Para>
-
-<Para>
-This monad underlies our implementation of arrays, mutable and
-immutable, and our implementation of I/O, including ``C calls''.
+Unboxed tuples aren't really exported by <Literal>PrelGHC</Literal>,
+they're available by default with <Option>-fglasgow-exts</Option>.  An
+unboxed tuple looks like this:
 </Para>
 
 <Para>
-The <Literal>ST</Literal> library, which provides access to the <Literal>ST</Literal> monad, is a
-GHC/Hugs extension library and is described in the separate <ULink
-URL="libs.html"
->GHC/Hugs Extension Libraries</ULink
-> document.
-</Para>
 
-</Sect1>
+<ProgramListing>
+(# e_1, ..., e_n #)
+</ProgramListing>
 
-<Sect1 id="glasgow-prim-arrays">
-<Title>Primitive arrays, mutable and otherwise
-</Title>
+</Para>
 
 <Para>
-<IndexTerm><Primary>primitive arrays (Glasgow extension)</Primary></IndexTerm>
-<IndexTerm><Primary>arrays, primitive (Glasgow extension)</Primary></IndexTerm>
+where <Literal>e&lowbar;1..e&lowbar;n</Literal> are expressions of any
+type (primitive or non-primitive).  The type of an unboxed tuple looks
+the same.
 </Para>
 
 <Para>
-GHC knows about quite a few flavours of Large Swathes of Bytes.
+Unboxed tuples are used for functions that need to return multiple
+values, but they avoid the heap allocation normally associated with
+using fully-fledged tuples.  When an unboxed tuple is returned, the
+components are put directly into registers or on the stack; the
+unboxed tuple itself does not have a composite representation.  Many
+of the primitive operations listed in this section return unboxed
+tuples.
 </Para>
 
 <Para>
-First, GHC distinguishes between primitive arrays of (boxed) Haskell
-objects (type <Literal>Array&num; obj</Literal>) and primitive arrays of bytes (type
-<Literal>ByteArray&num;</Literal>).
+There are some pretty stringent restrictions on the use of unboxed tuples:
 </Para>
 
 <Para>
-Second, it distinguishes between&hellip;
-<VariableList>
 
-<VarListEntry>
-<Term>Immutable:</Term>
+<ItemizedList>
 <ListItem>
+
 <Para>
-Arrays that do not change (as with ``standard'' Haskell arrays); you
-can only read from them.  Obviously, they do not need the care and
-attention of the state-transformer monad.
+ Unboxed tuple types are subject to the same restrictions as
+other unboxed types; i.e. they may not be stored in polymorphic data
+structures or passed to polymorphic functions.
+
 </Para>
 </ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>Mutable:</Term>
 <ListItem>
+
 <Para>
-Arrays that may be changed or ``mutated.''  All the operations on them
-live within the state-transformer monad and the updates happen
-<Emphasis>in-place</Emphasis>.
+ Unboxed tuples may only be constructed as the direct result of
+a function, and may only be deconstructed with a <Literal>case</Literal> expression.
+eg. the following are valid:
+
+
+<ProgramListing>
+f x y = (# x+1, y-1 #)
+g x = case f x x of { (# a, b #) -&#62; a + b }
+</ProgramListing>
+
+
+but the following are invalid:
+
+
+<ProgramListing>
+f x y = g (# x, y #)
+g (# x, y #) = x + y
+</ProgramListing>
+
+
 </Para>
 </ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>``Static'' (in C land):</Term>
 <ListItem>
+
 <Para>
-A C routine may pass an <Literal>Addr&num;</Literal> pointer back into Haskell land.  There
-are then primitive operations with which you may merrily grab values
-over in C land, by indexing off the ``static'' pointer.
+ No variable can have an unboxed tuple type.  This is illegal:
+
+
+<ProgramListing>
+f :: (# Int, Int #) -&#62; (# Int, Int #)
+f x = x
+</ProgramListing>
+
+
+because <VarName>x</VarName> has an unboxed tuple type.
+
 </Para>
 </ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>``Stable'' pointers:</Term>
-<ListItem>
+
+</ItemizedList>
+
+</Para>
+
 <Para>
-If, for some reason, you wish to hand a Haskell pointer (i.e.,
-<Emphasis>not</Emphasis> an unboxed value) to a C routine, you first make the
-pointer ``stable,'' so that the garbage collector won't forget that it
-exists.  That is, GHC provides a safe way to pass Haskell pointers to
-C.
+Note: we may relax some of these restrictions in the future.
 </Para>
 
 <Para>
-Please see <XRef LinkEnd="glasgow-stablePtrs"> for more details.
+The <Literal>IO</Literal> and <Literal>ST</Literal> monads use unboxed tuples to avoid unnecessary
+allocation during sequences of operations.
 </Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>``Foreign objects'':</Term>
-<ListItem>
+
+</Sect2>
+
+<Sect2>
+<Title>Character and numeric types</Title>
+
 <Para>
-A ``foreign object'' is a safe way to pass an external object (a
-C-allocated pointer, say) to Haskell and have Haskell do the Right
-Thing when it no longer references the object.  So, for example, C
-could pass a large bitmap over to Haskell and say ``please free this
-memory when you're done with it.''
+<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>
+There are the following obvious primitive types:
 </Para>
 
 <Para>
-Please see <XRef LinkEnd="glasgow-foreignObjs"> for more details.
+
+<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>
-</ListItem>
-</VarListEntry>
-</VariableList>
+
+<Para>
+If you really want to know their exact equivalents in C, see
+<Filename>ghc/includes/StgTypes.h</Filename> in the GHC source tree.
 </Para>
 
 <Para>
-The libraries section gives more details on all these ``primitive
-array'' types and the operations on them, <XRef LinkEnd="ghc-prelude">.  Some of these extensions
-are also supported by Hugs, and the supporting libraries are described
-in the <ULink
-URL="libs.html"
->GHC/Hugs Extension Libraries</ULink
->
-document.
+Literals for these types may be written as follows:
 </Para>
 
-</Sect1>
+<Para>
 
-<Sect1 id="glasgow-ccalls">
-<Title>Calling&nbsp;C directly from Haskell
-</Title>
+<ProgramListing>
+1#              an Int#
+1.2#            a Float#
+1.34##          a Double#
+'a'#            a Char#; for weird characters, use '\o&#60;octal&#62;'#
+"a"#            an Addr# (a `char *')
+</ProgramListing>
+
+<IndexTerm><Primary>literals, primitive</Primary></IndexTerm>
+<IndexTerm><Primary>constants, primitive</Primary></IndexTerm>
+<IndexTerm><Primary>numbers, primitive</Primary></IndexTerm>
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Comparison operations</Title>
 
 <Para>
-<IndexTerm><Primary>C calls (Glasgow extension)</Primary></IndexTerm>
-<IndexTerm><Primary>&lowbar;ccall&lowbar; (Glasgow extension)</Primary></IndexTerm>
-<IndexTerm><Primary>&lowbar;casm&lowbar; (Glasgow extension)</Primary></IndexTerm>
+<IndexTerm><Primary>comparisons, primitive</Primary></IndexTerm>
+<IndexTerm><Primary>operators, comparison</Primary></IndexTerm>
 </Para>
 
 <Para>
-GOOD ADVICE: Because this stuff is not Entirely Stable as far as names
-and things go, you would be well-advised to keep your C-callery
-corraled in a few modules, rather than sprinkled all over your code.
-It will then be quite easy to update later on.
+
+<ProgramListing>
+{&#62;,&#62;=,==,/=,&#60;,&#60;=}# :: Int# -&#62; Int# -&#62; Bool
+
+{gt,ge,eq,ne,lt,le}Char# :: Char# -&#62; Char# -&#62; Bool
+    -- ditto for Word# and Addr#
+</ProgramListing>
+
+<IndexTerm><Primary><literal>&#62;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>&#62;=&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>==&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>/=&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>&#60;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>&#60;=&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>gt&lcub;Char,Word,Addr&rcub;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>ge&lcub;Char,Word,Addr&rcub;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>eq&lcub;Char,Word,Addr&rcub;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>ne&lcub;Char,Word,Addr&rcub;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>lt&lcub;Char,Word,Addr&rcub;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>le&lcub;Char,Word,Addr&rcub;&num;</literal></Primary></IndexTerm>
 </Para>
 
-<Sect2 id="ccall-intro">
-<Title><Literal>&lowbar;ccall&lowbar;</Literal> and <Literal>&lowbar;casm&lowbar;</Literal>: an introduction
-</Title>
+</Sect2>
+
+<Sect2>
+<Title>Primitive-character operations</Title>
 
 <Para>
-The simplest way to use a simple C function
+<IndexTerm><Primary>characters, primitive operations</Primary></IndexTerm>
+<IndexTerm><Primary>operators, primitive character</Primary></IndexTerm>
 </Para>
 
 <Para>
 
 <ProgramListing>
-double fooC( FILE *in, char c, int i, double d, unsigned int u )
+ord# :: Char# -&#62; Int#
+chr# :: Int# -&#62; Char#
 </ProgramListing>
 
+<IndexTerm><Primary><literal>ord&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>chr&num;</literal></Primary></IndexTerm>
 </Para>
 
+</Sect2>
+
+<Sect2>
+<Title>Primitive-<Literal>Int</Literal> operations</Title>
+
 <Para>
-is to provide a Haskell wrapper:
+<IndexTerm><Primary>integers, primitive operations</Primary></IndexTerm>
+<IndexTerm><Primary>operators, primitive integer</Primary></IndexTerm>
 </Para>
 
 <Para>
 
 <ProgramListing>
-fooH :: Char -&#62; Int -&#62; Double -&#62; Word -&#62; IO Double
-fooH c i d w = _ccall_ fooC (``stdin''::Addr) c i d w
+{+,-,*,quotInt,remInt,gcdInt}# :: Int# -&#62; Int# -&#62; Int#
+negateInt# :: Int# -&#62; Int#
+
+iShiftL#, iShiftRA#, iShiftRL# :: Int# -&#62; Int# -&#62; Int#
+        -- shift left, right arithmetic, right logical
+
+addIntC#, subIntC#, mulIntC# :: Int# -> Int# -> (# Int#, Int# #)
+       -- add, subtract, multiply with carry
 </ProgramListing>
 
+<IndexTerm><Primary><literal>+&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>-&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>*&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>quotInt&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>remInt&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>gcdInt&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>iShiftL&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>iShiftRA&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>iShiftRL&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>addIntC&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>subIntC&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>mulIntC&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary>shift operations, integer</Primary></IndexTerm>
 </Para>
 
 <Para>
-The function <Literal>fooH</Literal> will unbox all of its arguments, call the C
-function <Literal>fooC</Literal> and box the corresponding arguments.
+<Emphasis>Note:</Emphasis> No error/overflow checking!
 </Para>
 
+</Sect2>
+
+<Sect2>
+<Title>Primitive-<Literal>Double</Literal> and <Literal>Float</Literal> operations</Title>
+
 <Para>
-One of the annoyances about <Literal>&lowbar;ccall&lowbar;</Literal>s is when the C types don't quite
-match the Haskell compiler's ideas.  For this, the <Literal>&lowbar;casm&lowbar;</Literal> variant
-may be just the ticket (NB: <Emphasis>no chance</Emphasis> of such code going
-through a native-code generator):
+<IndexTerm><Primary>floating point numbers, primitive</Primary></IndexTerm>
+<IndexTerm><Primary>operators, primitive floating point</Primary></IndexTerm>
 </Para>
 
 <Para>
 
 <ProgramListing>
-import Addr
-import CString
-
-oldGetEnv name
-  = _casm_ ``%r = getenv((char *) %0);'' name &#62;&#62;= \ litstring -&#62;
-    return (
-        if (litstring == nullAddr) then
-            Left ("Fail:oldGetEnv:"++name)
-        else
-            Right (unpackCString litstring)
-    )
+{+,-,*,/}##         :: Double# -&#62; Double# -&#62; Double#
+{&#60;,&#60;=,==,/=,&#62;=,&#62;}## :: Double# -&#62; Double# -&#62; Bool
+negateDouble#       :: Double# -&#62; Double#
+double2Int#         :: Double# -&#62; Int#
+int2Double#         :: Int#    -&#62; Double#
+
+{plus,minux,times,divide}Float# :: Float# -&#62; Float# -&#62; Float#
+{gt,ge,eq,ne,lt,le}Float# :: Float# -&#62; Float# -&#62; Bool
+negateFloat#        :: Float# -&#62; Float#
+float2Int#          :: Float# -&#62; Int#
+int2Float#          :: Int#   -&#62; Float#
 </ProgramListing>
 
 </Para>
 
 <Para>
-The first literal-literal argument to a <Literal>&lowbar;casm&lowbar;</Literal> is like a <Literal>printf</Literal>
-format: <Literal>&percnt;r</Literal> is replaced with the ``result,'' <Literal>&percnt;0</Literal>--<Literal>&percnt;n-1</Literal> are
-replaced with the 1st--nth arguments.  As you can see above, it is an
-easy way to do simple C&nbsp;casting.  Everything said about <Literal>&lowbar;ccall&lowbar;</Literal> goes
-for <Literal>&lowbar;casm&lowbar;</Literal> as well.
+<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 <Literal>&lowbar;casm&lowbar;</Literal> in your code does pose a problem to the compiler
-when it comes to generating an interface file for a freshly compiled
-module. Included in an interface file is the unfolding (if any) of a
-declaration. However, if a declaration's unfolding happens to contain
-a <Literal>&lowbar;casm&lowbar;</Literal>, its unfolding will <Emphasis>not</Emphasis> be emitted into the interface
-file even if it qualifies by all the other criteria. The reason why
-the compiler prevents this from happening is that unfolding <Literal>&lowbar;casm&lowbar;</Literal>s
-into an interface file unduly constrains how code that import your
-module have to be compiled. If an imported declaration is unfolded and
-it contains a <Literal>&lowbar;casm&lowbar;</Literal>, you now have to be using a compiler backend
-capable of dealing with it (i.e., the C compiler backend). If you are
-using the C compiler backend, the unfolded <Literal>&lowbar;casm&lowbar;</Literal> may still cause you
-problems since the C code snippet it contains may mention CPP symbols
-that were in scope when compiling the original module are not when
-compiling the importing module.
+<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
-<Literal>-funfold-casms-in-hi-file</Literal> 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>
 
-<Sect2 id="glasgow-literal-literals">
-<Title>Literal-literals
-</Title>
+<ProgramListing>
+expDouble#      :: Double# -&#62; Double#
+logDouble#      :: Double# -&#62; Double#
+sqrtDouble#     :: Double# -&#62; Double#
+sinDouble#      :: Double# -&#62; Double#
+cosDouble#      :: Double# -&#62; Double#
+tanDouble#      :: Double# -&#62; Double#
+asinDouble#     :: Double# -&#62; Double#
+acosDouble#     :: Double# -&#62; Double#
+atanDouble#     :: Double# -&#62; Double#
+sinhDouble#     :: Double# -&#62; Double#
+coshDouble#     :: Double# -&#62; Double#
+tanhDouble#     :: Double# -&#62; Double#
+powerDouble#    :: Double# -&#62; Double# -&#62; Double#
+</ProgramListing>
+
+<IndexTerm><Primary>trigonometric functions, primitive</Primary></IndexTerm>
+</Para>
 
 <Para>
-<IndexTerm><Primary>Literal-literals</Primary></IndexTerm>
+similarly for <Literal>Float&num;</Literal>.
 </Para>
 
 <Para>
-The literal-literal argument to <Literal>&lowbar;casm&lowbar;</Literal> can be made use of separately
-from the <Literal>&lowbar;casm&lowbar;</Literal> construct itself. Indeed, we've already used it:
+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 (``stdin''::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 <Literal>fooC</Literal> is given as a literal-literal,
-that is, a literal chunk of C code that will be inserted into the generated
-<Literal>.hc</Literal> code at the right place.
+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 <Literal>-fvia-C</Literal> directive), one can assist the
-C compiler in detecting type errors by using the <Literal>-&num;include</Literal> directive
-to provide <Literal>.h</Literal> files containing function headers.
+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>
-typedef unsigned long *StgForeignObj;
-typedef long StgInt;
-
-void          initialiseEFS (StgInt size);
-StgInt        terminateEFS (void);
-StgForeignObj emptyEFS(void);
-StgForeignObj updateEFS (StgForeignObj a, StgInt i, StgInt x);
-StgInt        lookupEFS (StgForeignObj a, StgInt i);
-</ProgramListing>
-
-</Para>
-
-<Para>
-You can find appropriate definitions for <Literal>StgInt</Literal>, <Literal>StgForeignObj</Literal>,
-etc using <Literal>gcc</Literal> on your architecture by consulting
-<Literal>ghc/includes/StgTypes.h</Literal>.  The following table summarises the
-relationship between Haskell types and C types.
-</Para>
-
-<Para>
-
-<InformalTable>
-<TGroup Cols="2">
-<ColSpec Align="Left" Colsep="0">
-<ColSpec Align="Left" Colsep="0">
-<TBody>
-<Row>
-<Entry><Emphasis>C type name</Emphasis> </Entry>
-<Entry> <Emphasis>Haskell Type</Emphasis> </Entry>
-</Row>
-
-<Row>
-<Entry>
-<Literal>StgChar</Literal> </Entry>
-<Entry> <Literal>Char&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgInt</Literal> </Entry>
-<Entry> <Literal>Int&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgWord</Literal> </Entry>
-<Entry> <Literal>Word&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgAddr</Literal> </Entry>
-<Entry> <Literal>Addr&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgFloat</Literal> </Entry>
-<Entry> <Literal>Float&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgDouble</Literal> </Entry>
-<Entry> <Literal>Double&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgArray</Literal> </Entry>
-<Entry> <Literal>Array&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgByteArray</Literal> </Entry>
-<Entry> <Literal>ByteArray&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgArray</Literal> </Entry>
-<Entry> <Literal>MutableArray&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgByteArray</Literal> </Entry>
-<Entry> <Literal>MutableByteArray&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgStablePtr</Literal> </Entry>
-<Entry> <Literal>StablePtr&num;</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgForeignObj</Literal> </Entry>
-<Entry> <Literal>ForeignObj&num;</Literal></Entry>
-</Row>
-</TBody>
-
-</TGroup>
-</InformalTable>
-</Para>
-
-<Para>
-Note that this approach is only <Emphasis>essential</Emphasis> for returning
-<Literal>float</Literal>s (or if <Literal>sizeof(int) != sizeof(int *)</Literal> on your
-architecture) but is a Good Thing for anyone who cares about writing
-solid code.  You're crazy not to do it.
+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 id="glasgow-stablePtrs">
-<Title>Subverting automatic unboxing with ``stable pointers''
-</Title>
+<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>
-<IndexTerm><Primary>stable pointers (Glasgow extension)</Primary></IndexTerm>
+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>
+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>
-The arguments of a <Literal>&lowbar;ccall&lowbar;</Literal> are automatically unboxed before the
-call.  There are two reasons why this is usually the Right Thing to
-do:
+<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>
 
-<ItemizedList>
-<ListItem>
+<ProgramListing>
+{gt,ge,eq,ne,lt,le}Word# :: Word# -> Word# -> Bool
 
-<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.
+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>
-</ListItem>
-<ListItem>
 
 <Para>
- Boxed values are stored on the Haskell heap and may be moved
-within the heap if a garbage collection occurs&mdash;that is, pointers
-to boxed objects are not <Emphasis>stable</Emphasis>.
+The 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>
-</ListItem>
 
-</ItemizedList>
+<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>
+<Title>Arrays</Title>
+
+<Para>
+<IndexTerm><Primary>arrays, primitive</Primary></IndexTerm>
 </Para>
 
 <Para>
-It is possible to subvert the unboxing process by creating a ``stable
-pointer'' to a value and passing the stable pointer instead.  For
-example, to pass/return an integer lazily to C functions <Literal>storeC</Literal> and
-<Literal>fetchC</Literal>, one might write:
+The type <Literal>Array&num; elt</Literal> is the type of primitive,
+unpointed arrays of values of type <Literal>elt</Literal>.
 </Para>
 
 <Para>
 
 <ProgramListing>
-storeH :: Int -&#62; IO ()
-storeH x = makeStablePtr x              &#62;&#62;= \ stable_x -&#62;
-           _ccall_ storeC stable_x
-
-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
+type Array# elt
 </ProgramListing>
 
+<IndexTerm><Primary><literal>Array&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+<Literal>Array&num;</Literal> is more primitive than a Haskell
+array&mdash;indeed, the Haskell <Literal>Array</Literal> interface is
+implemented using <Literal>Array&num;</Literal>&mdash;in that an
+<Literal>Array&num;</Literal> is indexed only by
+<Literal>Int&num;</Literal>s, starting at zero.  It is also more
+primitive by virtue of being unboxed.  That doesn't mean that it isn't
+a heap-allocated object&mdash;of course, it is.  Rather, being unboxed
+means that it is represented by a pointer to the array itself, and not
+to a thunk which will evaluate to the array (or to bottom).  The
+components of an <Literal>Array&num;</Literal> are themselves boxed.
 </Para>
 
 <Para>
-The garbage collector will refrain from throwing a stable pointer away
-until you explicitly call one of the following from C or Haskell.
+The type <Literal>ByteArray&num;</Literal> is similar to
+<Literal>Array&num;</Literal>, except that it contains just a string
+of (non-pointer) bytes.
 </Para>
 
 <Para>
 
 <ProgramListing>
-void freeStablePointer( StgStablePtr stablePtrToToss )
-freeStablePtr :: StablePtr a -&#62; IO ()
+type ByteArray#
 </ProgramListing>
 
+<IndexTerm><Primary><literal>ByteArray&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+Arrays of these types are useful when a Haskell program wishes to
+construct a value to pass to a C procedure. It is also possible to use
+them to build (say) arrays of unboxed characters for internal use in a
+Haskell program.  Given these uses, <Literal>ByteArray&num;</Literal>
+is deliberately a bit vague about the type of its components.
+Operations are provided to extract values of type
+<Literal>Char&num;</Literal>, <Literal>Int&num;</Literal>,
+<Literal>Float&num;</Literal>, <Literal>Double&num;</Literal>, and
+<Literal>Addr&num;</Literal> from arbitrary offsets within a
+<Literal>ByteArray&num;</Literal>.  (For type
+<Literal>Foo&num;</Literal>, the $i$th offset gets you the $i$th
+<Literal>Foo&num;</Literal>, not the <Literal>Foo&num;</Literal> at
+byte-position $i$.  Mumble.)  (If you want a
+<Literal>Word&num;</Literal>, grab an <Literal>Int&num;</Literal>,
+then coerce it.)
+</Para>
+
+<Para>
+Lastly, we have static byte-arrays, of type
+<Literal>Addr&num;</Literal> &lsqb;mentioned previously].  (Remember
+the duality between arrays and pointers in C.)  Arrays of this types
+are represented by a pointer to an array in the world outside Haskell,
+so this pointer is not followed by the garbage collector.  In other
+respects they are just like <Literal>ByteArray&num;</Literal>.  They
+are only needed in order to pass values from C to Haskell.
+</Para>
+
+</Sect2>
+
+<Sect2>
+<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>
-As with the use of <Literal>free</Literal> in C programs, GREAT CARE SHOULD BE
-EXERCISED to ensure these functions are called at the right time: too
-early and you get dangling references (and, if you're lucky, an error
-message from the runtime system); too late and you get space leaks.
+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>
-And to force evaluation of the argument within <Literal>fooC</Literal>, one would
-call one of the following C functions (according to type of argument).
+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>
-void     performIO  ( StgStablePtr stableIndex /* StablePtr s (IO ()) */ );
-StgInt   enterInt   ( StgStablePtr stableIndex /* StablePtr s Int */ );
-StgFloat enterFloat ( StgStablePtr stableIndex /* StablePtr s Float */ );
+indexCharArray#   :: ByteArray# -> Int# -> Char#
+indexIntArray#    :: ByteArray# -> Int# -> Int#
+indexAddrArray#   :: ByteArray# -> Int# -> Addr#
+indexFloatArray#  :: ByteArray# -> Int# -> Float#
+indexDoubleArray# :: ByteArray# -> Int# -> Double#
+
+indexCharOffAddr#   :: Addr# -> Int# -> Char#
+indexIntOffAddr#    :: Addr# -> Int# -> Int#
+indexFloatOffAddr#  :: Addr# -> Int# -> Float#
+indexDoubleOffAddr# :: Addr# -> Int# -> Double#
+indexAddrOffAddr#   :: Addr# -> Int# -> Addr#
+ -- Get an Addr# from an Addr# offset
 </ProgramListing>
 
+<IndexTerm><Primary><literal>indexCharArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexIntArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexAddrArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexFloatArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexDoubleArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexCharOffAddr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexIntOffAddr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexFloatOffAddr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexDoubleOffAddr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexAddrOffAddr&num;</literal></Primary></IndexTerm>
 </Para>
 
 <Para>
-<IndexTerm><Primary>performIO</Primary></IndexTerm>
-<IndexTerm><Primary>enterInt</Primary></IndexTerm>
-<IndexTerm><Primary>enterFloat</Primary></IndexTerm>
+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>
-Nota Bene: <Literal>&lowbar;ccall&lowbar;GC&lowbar;</Literal><IndexTerm><Primary>&lowbar;ccall&lowbar;GC&lowbar;</Primary></IndexTerm> must be used if any of
-these functions are used.
+Something a bit more interesting goes on when indexing arrays of boxed
+objects, because the result is simply the boxed object. So presumably
+it should be entered&mdash;we never usually return an unevaluated
+object!  This is a pain: primitive ops aren't supposed to do
+complicated things like enter objects.  The current solution is to
+return a single element unboxed tuple (see <XRef LinkEnd="unboxed-tuples">).
+</Para>
+
+<Para>
+
+<ProgramListing>
+indexArray#       :: Array# elt -> Int# -> (# elt #)
+</ProgramListing>
+
+<IndexTerm><Primary><literal>indexArray&num;</literal></Primary></IndexTerm>
 </Para>
 
 </Sect2>
 
-<Sect2 id="glasgow-foreignObjs">
-<Title>Foreign objects: pointing outside the Haskell heap
-</Title>
+<Sect2>
+<Title>The state type</Title>
 
 <Para>
-<IndexTerm><Primary>foreign objects (Glasgow extension)</Primary></IndexTerm>
+<IndexTerm><Primary><literal>state, primitive type</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>State&num;</literal></Primary></IndexTerm>
 </Para>
 
 <Para>
-There are two types that <Literal>ghc</Literal> programs can use to reference
-(heap-allocated) objects outside the Haskell world: <Literal>Addr</Literal> and
-<Literal>ForeignObj</Literal>.
+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>
-If you use <Literal>Addr</Literal>, it is up to you to the programmer to arrange
-allocation and deallocation of the objects.
+
+<ProgramListing>
+type State# s
+</ProgramListing>
+
 </Para>
 
 <Para>
-If you use <Literal>ForeignObj</Literal>, <Literal>ghc</Literal>'s garbage collector will call upon the
-user-supplied <Emphasis>finaliser</Emphasis> function to free the object when the
-Haskell world no longer can access the object.  (An object is
-associated with a finaliser function when the abstract
-Haskell type <Literal>ForeignObj</Literal> is created). The finaliser function is
-expressed in C, and is passed as argument the object:
+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 foreignFinaliser ( StgForeignObj fo )
+data RealWorld
 </ProgramListing>
 
 </Para>
 
+</Sect2>
+
+<Sect2>
+<Title>State of the world</Title>
+
 <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.
+A single, primitive, value of type <Literal>State&num; RealWorld</Literal> is provided.
 </Para>
 
 <Para>
 
 <ProgramListing>
-void GarbageCollect()
-performGC :: IO ()
+realWorld# :: State# RealWorld
 </ProgramListing>
 
+<IndexTerm><Primary>realWorld&num; state object</Primary></IndexTerm>
 </Para>
 
 <Para>
-More information on the programmers' interface to <Literal>ForeignObj</Literal> can be
-found in the library documentation.
+(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-avoiding-monads">
-<Title>Avoiding monads
-</Title>
+<Sect2 id="sect-mutable">
+<Title>Mutable arrays</Title>
 
 <Para>
-<IndexTerm><Primary>C calls to `pure C'</Primary></IndexTerm>
-<IndexTerm><Primary>unsafePerformIO</Primary></IndexTerm>
+<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>
-The <Literal>&lowbar;ccall&lowbar;</Literal> construct is part of the <Literal>IO</Literal> monad because 9 out of 10
-uses will be to call imperative functions with side effects such as
-<Literal>printf</Literal>.  Use of the monad ensures that these operations happen in a
-predictable order in spite of laziness and compiler optimisations.
+
+<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>
-To avoid having to be in the monad to call a C function, it is
-possible to use <Literal>unsafePerformIO</Literal>, which is available from the
-<Literal>IOExts</Literal> module.  There are three situations where one might like to
-call a C function from outside the IO world:
+<IndexTerm><Primary>mutable arrays, allocation</Primary></IndexTerm>
+<IndexTerm><Primary>arrays, allocation</Primary></IndexTerm>
+<IndexTerm><Primary>allocation, of mutable arrays</Primary></IndexTerm>
 </Para>
 
 <Para>
-
-<ItemizedList>
-<ListItem>
+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>
-Calling a function with no side-effects:
 
 <ProgramListing>
-atan2d :: Double -&#62; Double -&#62; Double
-atan2d y x = unsafePerformIO (_ccall_ atan2d y x)
+newArray#       :: Int# -> elt -> State# s -> (# State# s, MutableArray# s elt #)
 
-sincosd :: Double -&#62; (Double, Double)
-sincosd x = unsafePerformIO $ do
-        da &#60;- newDoubleArray (0, 1)
-        _casm_ ``sincosd( %0, &amp;((double *)%1[0]), &amp;((double *)%1[1]) );'' x da
-        s &#60;- readDoubleArray da 0
-        c &#60;- readDoubleArray da 1
-        return (s, c)
+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>
-</ListItem>
-<ListItem>
 
 <Para>
- Calling a set of functions which have side-effects but which can
-be used in a purely functional manner.
+The size of a <Literal>ByteArray&num;</Literal> is given in bytes.
+</Para>
 
-For example, an imperative implementation of a purely functional
-lookup-table might be accessed using the following functions.
+</Sect3>
 
+<Sect3>
+<Title>Reading and writing</Title>
+
+<Para>
+<IndexTerm><Primary>arrays, reading and writing</Primary></IndexTerm>
+</Para>
+
+<Para>
 
 <ProgramListing>
-empty  :: EFS x
-update :: EFS x -&#62; Int -&#62; x -&#62; EFS x
-lookup :: EFS a -&#62; Int -&#62; a
+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>
 
-empty = unsafePerformIO (_ccall_ emptyEFS)
+<Para>
+<IndexTerm><Primary>arrays, testing for equality</Primary></IndexTerm>
+</Para>
 
-update a i x = unsafePerformIO $
-        makeStablePtr x         &#62;&#62;= \ stable_x -&#62;
-        _ccall_ updateEFS a i stable_x
+<Para>
+One can take &ldquo;equality&rdquo; of mutable arrays.  What is compared is the
+<Emphasis>name</Emphasis> or reference to the mutable array, not its contents.
+</Para>
 
-lookup a i = unsafePerformIO $
-        _ccall_ lookupEFS a i   &#62;&#62;= \ stable_x -&#62;
-        deRefStablePtr stable_x
+<Para>
+
+<ProgramListing>
+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>
 
-You will almost always want to use <Literal>ForeignObj</Literal>s with this.
+<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>
-</ListItem>
-<ListItem>
 
 <Para>
- Calling a side-effecting function even though the results will
-be unpredictable.  For example the <Literal>trace</Literal> function is defined by:
+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>
-trace :: String -&#62; a -&#62; a
-trace string expr
-  = unsafePerformIO (
-        ((_ccall_ PreTraceHook sTDERR{-msg-}):: IO ())  &#62;&#62;
-        fputs sTDERR string                             &#62;&#62;
-        ((_ccall_ PostTraceHook sTDERR{-msg-}):: IO ()) &#62;&#62;
-        return expr )
-  where
-    sTDERR = (``stderr'' :: Addr)
+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>
 
-(This kind of use is not highly recommended&mdash;it is only really
-useful in debugging code.)
+<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>
-</ListItem>
 
-</ItemizedList>
+<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>
 
-<Sect2 id="ccall-gotchas">
-<Title>C-calling ``gotchas'' checklist
+</Sect1>
+
+<Sect1 id="glasgow-ST-monad">
+<Title>Primitive state-transformer monad
 </Title>
 
 <Para>
-<IndexTerm><Primary>C call dangers</Primary></IndexTerm>
-<IndexTerm><Primary>CCallable</Primary></IndexTerm>
-<IndexTerm><Primary>CReturnable</Primary></IndexTerm>
+<IndexTerm><Primary>state transformers (Glasgow extensions)</Primary></IndexTerm>
+<IndexTerm><Primary>ST monad (Glasgow extension)</Primary></IndexTerm>
 </Para>
 
 <Para>
-And some advice, too.
+This monad underlies our implementation of arrays, mutable and
+immutable, and our implementation of I/O, including &ldquo;C calls&rdquo;.
 </Para>
 
 <Para>
+The <Literal>ST</Literal> library, which provides access to the
+<Function>ST</Function> monad, is described in <xref
+linkend="sec-ST">.
+</Para>
 
-<ItemizedList>
-<ListItem>
+</Sect1>
+
+<Sect1 id="glasgow-prim-arrays">
+<Title>Primitive arrays, mutable and otherwise
+</Title>
 
 <Para>
- For modules that use <Literal>&lowbar;ccall&lowbar;</Literal>s, etc., compile with
-<Literal>-fvia-C</Literal>.<IndexTerm><Primary>-fvia-C option</Primary></IndexTerm> You don't have to, but you should.
+<IndexTerm><Primary>primitive arrays (Glasgow extension)</Primary></IndexTerm>
+<IndexTerm><Primary>arrays, primitive (Glasgow extension)</Primary></IndexTerm>
+</Para>
 
-Also, use the <Literal>-&num;include "prototypes.h"</Literal> flag (hack) to inform the C
-compiler of the fully-prototyped types of all the C functions you
-call.  (<XRef LinkEnd="glasgow-foreign-headers"> says more about this&hellip;)
+<Para>
+GHC knows about quite a few flavours of Large Swathes of Bytes.
+</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>).
+</Para>
 
-This scheme is the <Emphasis>only</Emphasis> way that you will get <Emphasis>any</Emphasis>
-typechecking of your <Literal>&lowbar;ccall&lowbar;</Literal>s.  (It shouldn't be that way, but&hellip;).
-GHC will pass the flag <Literal>-Wimplicit</Literal> to gcc so that you'll get warnings
-if any <Literal>&lowbar;ccall&lowbar;</Literal>ed functions have no prototypes.
+<Para>
+Second, it distinguishes between&hellip;
+<VariableList>
 
+<VarListEntry>
+<Term>Immutable:</Term>
+<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.
+</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>.
 </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.
+</Para>
+</ListItem>
+</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>
 
 <Para>
-Try to avoid <Literal>&lowbar;ccall&lowbar;</Literal>s to C&nbsp;functions that take <Literal>float</Literal>
-arguments or return <Literal>float</Literal> results.  Reason: if you do, you will
-become entangled in (ANSI?) C's rules for when arguments/results are
-promoted to <Literal>doubles</Literal>.  It's a nightmare and just not worth it.
-Use <Literal>doubles</Literal> if possible.
+Please see <XRef LinkEnd="sec-stable-pointers"> for more details.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>&ldquo;Foreign objects&rdquo;:</Term>
+<ListItem>
+<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;
+</Para>
 
-If you do use <Literal>floats</Literal>, check and re-check that the right thing is
-happening.  Perhaps compile with <Literal>-keep-hc-file-too</Literal> and look at
-the intermediate C (<Literal>.hc</Literal> file).
+<Para>
+Please see <XRef LinkEnd="sec-ForeignObj"> for more details.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
 
+<Para>
+The libraries documentatation gives more details on all these
+&ldquo;primitive array&rdquo; types and the operations on them.
 </Para>
-</ListItem>
-<ListItem>
-
-<Para>
- The compiler uses two non-standard type-classes when
-type-checking the arguments and results of <Literal>&lowbar;ccall&lowbar;</Literal>: the arguments
-(respectively result) of <Literal>&lowbar;ccall&lowbar;</Literal> must be instances of the class
-<Literal>CCallable</Literal> (respectively <Literal>CReturnable</Literal>).  Both classes may be
-imported from the module <Literal>CCall</Literal>, but this should only be
-necessary if you want to define a new instance.  (Neither class
-defines any methods&mdash;their only function is to keep the
-type-checker happy.)
-
-The type checker must be able to figure out just which of the
-C-callable/returnable types is being used.  If it can't, you have to
-add type signatures. For example,
-
-
-<ProgramListing>
-f x = _ccall_ foo x
-</ProgramListing>
-
-
-is not good enough, because the compiler can't work out what type <Literal>x</Literal>
-is, nor what type the <Literal>&lowbar;ccall&lowbar;</Literal> returns.  You have to write, say:
-
-
-<ProgramListing>
-f :: Int -&#62; IO Double
-f x = _ccall_ foo x
-</ProgramListing>
-
-
-This table summarises the standard instances of these classes.
-
-<InformalTable>
-<TGroup Cols="4">
-<ColSpec Align="Left" Colsep="0">
-<ColSpec Align="Left" Colsep="0">
-<ColSpec Align="Left" Colsep="0">
-<ColSpec Align="Left" Colsep="0">
-<TBody>
-<Row>
-<Entry><Emphasis>Type</Emphasis> </Entry>
-<Entry><Emphasis>CCallable</Emphasis></Entry>
-<Entry><Emphasis>CReturnable</Emphasis> </Entry>
-<Entry><Emphasis>Which is probably&hellip;</Emphasis> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Char</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>unsigned char</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Int</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>long int</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Word</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>unsigned long int</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Addr</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>void *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Float</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>float</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Double</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>double</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>()</Literal> </Entry>
-<Entry> No </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>void</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>[Char]</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>char *</Literal> (null-terminated) </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Array</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>ByteArray</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>MutableArray</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>MutableByteArray</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>State</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> nothing!</Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StablePtr</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>ForeignObjs</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> see later </Entry>
-</Row>
-
-</TBody>
-
-</TGroup>
-</InformalTable>
-
-Actually, the <Literal>Word</Literal> type is defined as being the same size as a
-pointer on the target architecture, which is <Emphasis>probably</Emphasis>
-<Literal>unsigned long int</Literal>.
-
-The brave and careful programmer can add their own instances of these
-classes for the following types:
 
+</Sect1>
 
-<ItemizedList>
-<ListItem>
 
-<Para>
-A <Emphasis>boxed-primitive</Emphasis> type may be made an instance of both
-<Literal>CCallable</Literal> and <Literal>CReturnable</Literal>.
+<Sect1 id="pattern-guards">
+<Title>Pattern guards</Title>
 
-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:
+<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>
 
+<Para>
+Suppose we have an abstract data type of finite maps, with a
+lookup operation:
 
 <ProgramListing>
-Int
-Double
-data XDisplay = XDisplay Addr#
-data EFS a = EFS# ForeignObj#
+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>
 
+<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>
+The auxiliary functions are 
+</Para>
 
 <ProgramListing>
-instance CCallable   (EFS a)
-instance CReturnable (EFS a)
+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>
-</ListItem>
-<ListItem>
+
+<ProgramListing>
+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>
- Any datatype with a single nullary constructor may be made an
-instance of <Literal>CReturnable</Literal>.  For example:
+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>
 
+<Para>
+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>
 
-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;)
+<ProgramListing>
+f x | [y] <- x
+    , y > 3
+    , Just z <- h y
+    = ...
+</ProgramListing>
+
+<Para>
+Haskell's current guards therefore emerge as a special case, in which the
+qualifier list has just one element, a boolean expression.
 </Para>
-</ListItem>
+</Sect1>
 
-</ItemizedList>
+  <sect1 id="sec-ffi">
+    <title>The foreign interface</title>
+
+    <para>The foreign interface consists of the following components:</para>
+
+    <itemizedlist>
+      <listitem>
+       <para>The Foreign Function Interface language specification
+       (included in this manual, in <xref linkend="ffi">).</para>
+      </listitem>
+
+      <listitem>
+       <para>The <literal>Foreign</literal> module (see <xref
+       linkend="sec-Foreign">) collects together several interfaces
+       which are useful in specifying foreign language
+       interfaces, including the following:</para>
+
+       <itemizedlist>
+         <listitem>
+           <para>The <literal>ForeignObj</literal> module (see <xref
+           linkend="sec-ForeignObj">), for managing pointers from
+           Haskell into the outside world.</para>
+         </listitem>
+      
+         <listitem>
+           <para>The <literal>StablePtr</literal> module (see <xref
+           linkend="sec-stable-pointers">), for managing pointers
+           into Haskell from the outside world.</para>
+         </listitem>
+      
+         <listitem>
+           <para>The <literal>CTypes</literal> module (see <xref
+           linkend="sec-CTypes">) gives Haskell equivalents for the
+           standard C datatypes, for use in making Haskell bindings
+           to existing C libraries.</para>
+         </listitem>
+      
+         <listitem>
+           <para>The <literal>CTypesISO</literal> module (see <xref
+           linkend="sec-CTypesISO">) gives Haskell equivalents for C
+           types defined by the ISO C standard.</para>
+         </listitem>
+      
+         <listitem>
+           <para>The <literal>Storable</literal> library, for
+           primitive marshalling of data types between Haskell and
+           the foreign language.</para>
+         </listitem>
+       </itemizedlist>
+
+      </listitem>
+    </itemizedlist>
+
+<para>The following sections also give some hints and tips on the use
+of the foreign function interface in GHC.</para>
 
+<Sect2 id="glasgow-foreign-headers">
+<Title>Using function headers
+</Title>
 
+<Para>
+<IndexTerm><Primary>C calls, function headers</Primary></IndexTerm>
 </Para>
-</ListItem>
-<ListItem>
 
 <Para>
- The code-generator will complain if you attempt to use <Literal>&percnt;r</Literal> in
-a <Literal>&lowbar;casm&lowbar;</Literal> whose result type is <Literal>IO ()</Literal>; or if you don't use <Literal>&percnt;r</Literal>
-<Emphasis>precisely</Emphasis> once for any other result type.  These messages are
-supposed to be helpful and catch bugs&mdash;please tell us if they wreck
-your life.
-
+When generating C (using the <Option>-fvia-C</Option> directive), one can assist the
+C compiler in detecting type errors by using the <Command>-&num;include</Command> directive
+to provide <Filename>.h</Filename> files containing function headers.
 </Para>
-</ListItem>
-<ListItem>
 
 <Para>
- If you call out to C code which may trigger the Haskell garbage
-collector or create new threads (examples of this later&hellip;), then you
-must use the <Literal>&lowbar;ccall&lowbar;GC&lowbar;</Literal><IndexTerm><Primary>&lowbar;ccall&lowbar;GC&lowbar; primitive</Primary></IndexTerm> or
-<Literal>&lowbar;casm&lowbar;GC&lowbar;</Literal><IndexTerm><Primary>&lowbar;casm&lowbar;GC&lowbar; primitive</Primary></IndexTerm> variant of C-calls.  (This
-does not work with the native code generator - use <Literal>\fvia-C</Literal>.) This
-stuff is hairy with a capital H!
+For example,
 </Para>
-</ListItem>
 
-</ItemizedList>
+<Para>
 
+<ProgramListing>
+#include "HsFFI.h"
+
+void         initialiseEFS (HsInt size);
+HsInt        terminateEFS (void);
+HsForeignObj emptyEFS(void);
+HsForeignObj updateEFS (HsForeignObj a, HsInt i, HsInt x);
+HsInt        lookupEFS (HsForeignObj a, HsInt i);
+</ProgramListing>
 </Para>
 
+      <para>The types <literal>HsInt</literal>,
+      <literal>HsForeignObj</literal> etc. are described in <xref
+      linkend="sec-mapping-table">.</Para>
+
+      <Para>Note that this approach is only
+      <Emphasis>essential</Emphasis> for returning
+      <Literal>float</Literal>s (or if <Literal>sizeof(int) !=
+      sizeof(int *)</Literal> on your architecture) but is a Good
+      Thing for anyone who cares about writing solid code.  You're
+      crazy not to do it.</Para>
+
 </Sect2>
 
 </Sect1>
@@ -1156,12 +1583,11 @@ stuff is hairy with a capital H!
 </Title>
 
 <Para>
-This section documents GHC's implementation of multi-paramter type
+This section documents GHC's implementation of multi-parameter type
 classes.  There's lots of background in the paper <ULink
-URL="http://www.dcs.gla.ac.uk/~simonpj/multi.ps.gz"
->Type classes: exploring the design space</ULink
-> (Simon Peyton
-Jones, Mark Jones, Erik Meijer).
+URL="http://research.microsoft.com/~simonpj/multi.ps.gz" >Type
+classes: exploring the design space</ULink > (Simon Peyton Jones, Mark
+Jones, Erik Meijer).
 </Para>
 
 <Para>
@@ -1190,7 +1616,7 @@ type:
 <Para>
 
 <ProgramListing>
-  forall tv1..tvn (c1, ...,cn) =&#62; type
+  forall tv1..tvn (c1, ...,cn) => type
 </ProgramListing>
 
 </Para>
@@ -1218,7 +1644,7 @@ ambiguity. Here, for example, is an illegal type:
 
 
 <ProgramListing>
-  forall a. Eq a =&#62; Int
+  forall a. Eq a => Int
 </ProgramListing>
 
 
@@ -1242,7 +1668,7 @@ universally quantified type variable <Literal>b</Literal>:
 
 
 <ProgramListing>
-  forall a. C a b =&#62; burble
+  forall a. C a b => burble
 </ProgramListing>
 
 
@@ -1251,7 +1677,7 @@ mention <Literal>a</Literal>:
 
 
 <ProgramListing>
-  forall a. Eq b =&#62; burble
+  forall a. Eq b => burble
 </ProgramListing>
 
 
@@ -1283,8 +1709,8 @@ are perfectly OK
 <Para>
 
 <ProgramListing>
-  f :: Eq (m a) =&#62; [m a] -&#62; [m a]
-  g :: Eq [a] =&#62; ...
+  f :: Eq (m a) => [m a] -> [m a]
+  g :: Eq [a] => ...
 </ProgramListing>
 
 </Para>
@@ -1309,7 +1735,7 @@ This choice recovers principal types, a property that Haskell 1.4 does not have.
 
 <ProgramListing>
   class Collection c a where
-    union :: c a -&#62; c a -&#62; c a
+    union :: c a -> c a -> c a
     ...etc.
 </ProgramListing>
 
@@ -1327,10 +1753,10 @@ this is OK:
 
 <ProgramListing>
   class C a where {
-    op :: D b =&#62; a -&#62; b -&#62; b
+    op :: D b => a -> b -> b
   }
 
-  class C a =&#62; D a where { ... }
+  class C a => D a where { ... }
 </ProgramListing>
 
 
@@ -1349,11 +1775,11 @@ be acyclic</Emphasis>.  So these class declarations are OK:
 
 
 <ProgramListing>
-  class Functor (m k) =&#62; FiniteMap m k where
+  class Functor (m k) => FiniteMap m k where
     ...
 
-  class (Monad m, Monad (t m)) =&#62; Transform t m where
-    lift :: m a -&#62; (t m) a
+  class (Monad m, Monad (t m)) => Transform t m where
+    lift :: m a -> (t m) a
 </ProgramListing>
 
 
@@ -1371,7 +1797,7 @@ Thus:
 
 <ProgramListing>
   class Collection c a where
-    mapC :: Collection c b =&#62; (a-&#62;b) -&#62; c a -&#62; c b
+    mapC :: Collection c b => (a->b) -> c a -> c b
 </ProgramListing>
 
 
@@ -1382,7 +1808,7 @@ is OK because the constraint <Literal>(Collection a b)</Literal> mentions
 
 <ProgramListing>
   class C a where
-    op :: Eq a =&#62; (a,b) -&#62; (a,b)
+    op :: Eq a => (a,b) -> (a,b)
 </ProgramListing>
 
 
@@ -1393,8 +1819,8 @@ superclass context:
 
 
 <ProgramListing>
-  class Eq a =&#62; C a where
-    op ::(a,b) -&#62; (a,b)
+  class Eq a => C a where
+    op ::(a,b) -> (a,b)
 </ProgramListing>
 
 
@@ -1414,7 +1840,7 @@ the class type variables</Emphasis>.  For example:
 <ProgramListing>
   class Coll s a where
     empty  :: s
-    insert :: s -&#62; a -&#62; s
+    insert :: s -> a -> s
 </ProgramListing>
 
 
@@ -1429,7 +1855,7 @@ example, <Literal>Coll</Literal> might be rewritten
 <ProgramListing>
   class Coll s a where
     empty  :: s a
-    insert :: s a -&#62; a -&#62; s a
+    insert :: s a -> a -> s a
 </ProgramListing>
 
 
@@ -1443,8 +1869,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>
 
 
@@ -1471,15 +1897,15 @@ declarations
 
 
 <ProgramListing>
-  instance context1 =&#62; C type1 where ...
-  instance context2 =&#62; C type2 where ...
+  instance context1 => C type1 where ...
+  instance context2 => C type2 where ...
 </ProgramListing>
 
 
 "overlap" if <Literal>type1</Literal> and <Literal>type2</Literal> unify
 
 However, if you give the command line option
-<Literal>-fallow-overlapping-instances</Literal><IndexTerm><Primary>-fallow-overlapping-instances
+<Option>-fallow-overlapping-instances</Option><IndexTerm><Primary>-fallow-overlapping-instances
 option</Primary></IndexTerm> then two overlapping instance declarations are permitted
 iff
 
@@ -1548,7 +1974,7 @@ change that decision, at least for <Literal>Main</Literal>.)
 <Para>
  <Emphasis>There are no restrictions on the type in an instance
 <Emphasis>head</Emphasis>, except that at least one must not be a type variable</Emphasis>.
-The instance "head" is the bit after the "=&#62;" in an instance decl. For
+The instance "head" is the bit after the "=>" in an instance decl. For
 example, these are OK:
 
 
@@ -1577,7 +2003,7 @@ loop if it wasn't excluded:
 
 
 <ProgramListing>
-  instance C a =&#62; C a where ...
+  instance C a => C a where ...
 </ProgramListing>
 
 
@@ -1598,9 +2024,9 @@ effect of a "class synonym":
 
 
 <ProgramListing>
-  class (C1 a, C2 a, C3 a) =&#62; C a where { }
+  class (C1 a, C2 a, C3 a) => C a where { }
 
-  instance (C1 a, C2 a, C3 a) =&#62; C a where { }
+  instance (C1 a, C2 a, C3 a) => C a where { }
 </ProgramListing>
 
 
@@ -1608,7 +2034,7 @@ This allows you to write shorter signatures:
 
 
 <ProgramListing>
-  f :: C a =&#62; ...
+  f :: C a => ...
 </ProgramListing>
 
 
@@ -1616,13 +2042,13 @@ instead of
 
 
 <ProgramListing>
-  f :: (C1 a, C2 a, C3 a) =&#62; ...
+  f :: (C1 a, C2 a, C3 a) => ...
 </ProgramListing>
 
 
 I'm on the lookout for a simple rule that preserves decidability while
 allowing these idioms.  The experimental flag
-<Literal>-fallow-undecidable-instances</Literal><IndexTerm><Primary>-fallow-undecidable-instances
+<Option>-fallow-undecidable-instances</Option><IndexTerm><Primary>-fallow-undecidable-instances
 option</Primary></IndexTerm> lifts this restriction, allowing all the types in an
 instance head to be type variables.
 
@@ -1675,7 +2101,7 @@ be type variables</Emphasis>. Thus
 
 
 <ProgramListing>
-instance C a b =&#62; Eq (a,b) where ...
+instance C a b => Eq (a,b) where ...
 </ProgramListing>
 
 
@@ -1683,7 +2109,7 @@ is OK, but
 
 
 <ProgramListing>
-instance C Int b =&#62; Foo b where ...
+instance C Int b => Foo b where ...
 </ProgramListing>
 
 
@@ -1692,11 +2118,11 @@ reduction terminates.
 
 Voluminous correspondence on the Haskell mailing list has convinced me
 that it's worth experimenting with a more liberal rule.  If you use
-the flag <Literal>-fallow-undecidable-instances</Literal> you can use arbitrary
+the flag <Option>-fallow-undecidable-instances</Option> can use arbitrary
 types in an instance context.  Termination is ensured by having a
 fixed-depth recursion stack.  If you exceed the stack depth you get a
 sort of backtrace, and the opportunity to increase the stack depth
-with <Literal>-fcontext-stack</Literal><Emphasis>N</Emphasis>.
+with <Option>-fcontext-stack</Option><Emphasis>N</Emphasis>.
 
 </Para>
 </ListItem>
@@ -1721,7 +2147,7 @@ syntax for this now agrees with Hugs's, namely:
 <Para>
 
 <ProgramListing>
-        forall a b. (Ord a, Eq  b) =&#62; a -&#62; b -&#62; a
+        forall a b. (Ord a, Eq  b) => a -> b -> a
 </ProgramListing>
 
 </Para>
@@ -1739,7 +2165,7 @@ allows us to say exactly what this means.  For example:
 <Para>
 
 <ProgramListing>
-        g :: b -&#62; b
+        g :: b -> b
 </ProgramListing>
 
 </Para>
@@ -1751,7 +2177,7 @@ means this:
 <Para>
 
 <ProgramListing>
-        g :: forall b. (b -&#62; b)
+        g :: forall b. (b -> b)
 </ProgramListing>
 
 </Para>
@@ -1772,13 +2198,13 @@ the types of the constructor arguments.  Here are several examples:
 <Para>
 
 <ProgramListing>
-data T a = T1 (forall b. b -&#62; b -&#62; b) a
+data T a = T1 (forall b. b -> b -> b) a
 
-data MonadT m = MkMonad { return :: forall a. a -&#62; m a,
-                          bind   :: forall a b. m a -&#62; (a -&#62; m b) -&#62; m b
+data MonadT m = MkMonad { return :: forall a. a -> m a,
+                          bind   :: forall a b. m a -> (a -> m b) -> m b
                         }
 
-newtype Swizzle = MkSwizzle (Ord a =&#62; [a] -&#62; [a])
+newtype Swizzle = MkSwizzle (Ord a => [a] -> [a])
 </ProgramListing>
 
 </Para>
@@ -1791,11 +2217,11 @@ types, in which there is a for-all in the argument types.:
 <Para>
 
 <ProgramListing>
-T1 :: forall a. (forall b. b -&#62; b -&#62; b) -&#62; a -&#62; T1 a
-MkMonad :: forall m. (forall a. a -&#62; m a)
-                  -&#62; (forall a b. m a -&#62; (a -&#62; m b) -&#62; m b)
-                  -&#62; MonadT m
-MkSwizzle :: (Ord a =&#62; [a] -&#62; [a]) -&#62; Swizzle
+T1 :: forall a. (forall b. b -> b -> b) -> a -> T a
+MkMonad :: forall m. (forall a. a -> m a)
+                  -> (forall a b. m a -> (a -> m b) -> m b)
+                  -> MonadT m
+MkSwizzle :: (Ord a => [a] -> [a]) -> Swizzle
 </ProgramListing>
 
 </Para>
@@ -1803,7 +2229,7 @@ MkSwizzle :: (Ord a =&#62; [a] -&#62; [a]) -&#62; Swizzle
 <Para>
 Notice that you don't need to use a <Literal>forall</Literal> if there's an
 explicit context.  For example in the first argument of the
-constructor <Literal>MkSwizzle</Literal>, an implicit "<Literal>forall a.</Literal>" is
+constructor <Function>MkSwizzle</Function>, an implicit "<Literal>forall a.</Literal>" is
 prefixed to the argument type.  The implicit <Literal>forall</Literal>
 quantifies all type variables that are not already in scope, and are
 mentioned in the type quantified over.
@@ -1814,13 +2240,13 @@ As for type signatures, implicit quantification happens for non-overloaded
 types too.  So if you write this:
 
 <ProgramListing>
-  data T a = MkT (Either a b) (b -&#62; b)
+  data T a = MkT (Either a b) (b -> b)
 </ProgramListing>
 
 it's just as if you had written this:
 
 <ProgramListing>
-  data T a = MkT (forall b. Either a b) (forall b. b -&#62; b)
+  data T a = MkT (forall b. Either a b) (forall b. b -> b)
 </ProgramListing>
 
 That is, since the type variable <Literal>b</Literal> isn't in scope, it's
@@ -1842,15 +2268,15 @@ the constructor to suitable values, just as usual.  For example,
 <Para>
 
 <ProgramListing>
-(T1 (\xy-&#62;x) 3) :: T Int
+(T1 (\xy->x) 3) :: T Int
 
 (MkSwizzle sort)    :: Swizzle
 (MkSwizzle reverse) :: Swizzle
 
 (let r x = Just x
      b m k = case m of
-                Just y -&#62; k y
-                Nothing -&#62; Nothing
+                Just y -> k y
+                Nothing -> Nothing
   in
   MkMonad r b) :: MonadT Maybe
 </ProgramListing>
@@ -1859,7 +2285,7 @@ the constructor to suitable values, just as usual.  For example,
 
 <Para>
 The type of the argument can, as usual, be more general than the type
-required, as <Literal>(MkSwizzle reverse)</Literal> shows.  (<Literal>reverse</Literal>
+required, as <Literal>(MkSwizzle reverse)</Literal> shows.  (<Function>reverse</Function>
 does not need the <Literal>Ord</Literal> constraint.)
 </Para>
 
@@ -1876,23 +2302,23 @@ polymorphic types.  For example:
 <Para>
 
 <ProgramListing>
-        f :: T a -&#62; a -&#62; (a, Char)
+        f :: T a -> a -> (a, Char)
         f (T1 f k) x = (f k x, f 'c' 'd')
 
-        g :: (Ord a, Ord b) =&#62; Swizzle -&#62; [a] -&#62; (a -&#62; b) -&#62; [b]
+        g :: (Ord a, Ord b) => Swizzle -> [a] -> (a -> b) -> [b]
         g (MkSwizzle s) xs f = s (map f (s xs))
 
-        h :: MonadT m -&#62; [m a] -&#62; m [a]
+        h :: MonadT m -> [m a] -> m [a]
         h m [] = return m []
-        h m (x:xs) = bind m x           $ \y -&#62;
-                      bind m (h m xs)   $ \ys -&#62;
+        h m (x:xs) = bind m x           $ \y ->
+                      bind m (h m xs)   $ \ys ->
                       return m (y:ys)
 </ProgramListing>
 
 </Para>
 
 <Para>
-In the function <Literal>h</Literal> we use the record selectors <Literal>return</Literal>
+In the function <Function>h</Function> we use the record selectors <Literal>return</Literal>
 and <Literal>bind</Literal> to extract the polymorphic bind and return functions
 from the <Literal>MonadT</Literal> data structure, rather than using pattern
 matching.
@@ -1905,7 +2331,7 @@ For example:
 <ProgramListing>
         newtype TIM s a = TIM (ST s (Maybe a))
 
-        runTIM :: (forall s. TIM s a) -&#62; Maybe a
+        runTIM :: (forall s. TIM s a) -> Maybe a
         runTIM (TIM m) = runST m
 </ProgramListing>
 
@@ -1917,8 +2343,8 @@ an argument of type <Literal>(forall s. TIM s a)</Literal>.  Instead you
 must bind the variable and pattern match in the right hand side:
 
 <ProgramListing>
-        runTIM :: (forall s. TIM s a) -&#62; Maybe a
-        runTIM tm = case tm of { TIM m -&#62; runST m }
+        runTIM :: (forall s. TIM s a) -> Maybe a
+        runTIM tm = case tm of { TIM m -> runST m }
 </ProgramListing>
 
 The <Literal>tm</Literal> on the right hand side is (invisibly) instantiated, like
@@ -1954,7 +2380,7 @@ this rule</Emphasis>.  The restriction makes type inference feasible.
 
 <Para>
 In the illegal example, the sub-expression <Literal>MkSwizzle</Literal> has the
-polymorphic type <Literal>(Ord b =&#62; [b] -&#62; [b]) -&#62; Swizzle</Literal> and is not
+polymorphic type <Literal>(Ord b => [b] -> [b]) -> Swizzle</Literal> and is not
 a sub-expression of an enclosing application.  On the other hand, this
 expression is OK:
 </Para>
@@ -1962,14 +2388,14 @@ expression is OK:
 <Para>
 
 <ProgramListing>
-        map (T1 (\a b -&#62; a)) [1,2,3]
+        map (T1 (\a b -> a)) [1,2,3]
 </ProgramListing>
 
 </Para>
 
 <Para>
-even though it involves a partial application of <Literal>T1</Literal>, because
-the sub-expression <Literal>T1 (\a b -&#62; a)</Literal> has type <Literal>Int -&#62; T
+even though it involves a partial application of <Function>T1</Function>, because
+the sub-expression <Literal>T1 (\a b -> a)</Literal> has type <Literal>Int -> T
 Int</Literal>.
 </Para>
 
@@ -1981,7 +2407,7 @@ Int</Literal>.
 
 <Para>
 Once you have data constructors with universally-quantified fields, or
-constants such as <Literal>runST</Literal> that have rank-2 types, it isn't long
+constants such as <Constant>runST</Constant> that have rank-2 types, it isn't long
 before you discover that you need more!  Consider:
 </Para>
 
@@ -1994,13 +2420,13 @@ before you discover that you need more!  Consider:
 </Para>
 
 <Para>
-<Literal>mkTs</Literal> is a fuction that constructs some values of type
+<Function>mkTs</Function> is a fuction that constructs some values of type
 <Literal>T</Literal>, using some pieces passed to it.  The trouble is that since
 <Literal>f</Literal> is a function argument, Haskell assumes that it is
-monomorphic, so we'll get a type error when applying <Literal>T1</Literal> to
+monomorphic, so we'll get a type error when applying <Function>T1</Function> to
 it.  This is a rather silly example, but the problem really bites in
 practice.  Lots of people trip over the fact that you can't make
-"wrappers functions" for <Literal>runST</Literal> for exactly the same reason.
+"wrappers functions" for <Constant>runST</Constant> for exactly the same reason.
 In short, it is impossible to build abstractions around functions with
 rank-2 types.
 </Para>
@@ -2014,7 +2440,7 @@ constructors), thus:
 <Para>
 
 <ProgramListing>
-  mkTs :: (forall b. b -&#62; b -&#62; b) -&#62; a -&#62; [T a]
+  mkTs :: (forall b. b -> b -> b) -> a -> [T a]
   mkTs f x y = [T1 f x, T1 f y]
 </ProgramListing>
 
@@ -2022,9 +2448,9 @@ constructors), thus:
 
 <Para>
 This type signature tells the compiler to attribute <Literal>f</Literal> with
-the polymorphic type <Literal>(forall b. b -&#62; b -&#62; b)</Literal> when type
-checking the body of <Literal>mkTs</Literal>, so now the application of
-<Literal>T1</Literal> is fine.
+the polymorphic type <Literal>(forall b. b -> b -> b)</Literal> when type
+checking the body of <Function>mkTs</Function>, so now the application of
+<Function>T1</Function> is fine.
 </Para>
 
 <Para>
@@ -2042,10 +2468,10 @@ grammar:
 
 
 <ProgramListing>
-   rank2type ::= [forall tyvars .] [context =&#62;] funty
-   funty     ::= ([forall tyvars .] [context =&#62;] ty) -&#62; funty
-               | ty
-   ty        ::= ...current Haskell monotype syntax...
+rank2type ::= [forall tyvars .] [context =>] funty
+funty     ::= ([forall tyvars .] [context =>] ty) -> funty
+            | ty
+ty        ::= ...current Haskell monotype syntax...
 </ProgramListing>
 
 
@@ -2060,12 +2486,12 @@ or at the top level of a function argument.
  There is a restriction on the definition of a function whose
 type signature is a rank-2 type: the polymorphic arguments must be
 matched on the left hand side of the "<Literal>=</Literal>" sign.  You can't
-define <Literal>mkTs</Literal> like this:
+define <Function>mkTs</Function> like this:
 
 
 <ProgramListing>
-  mkTs :: (forall b. b -&#62; b -&#62; b) -&#62; a -&#62; [T a]
-  mkTs = \ f x y -&#62; [T1 f x, T1 f y]
+mkTs :: (forall b. b -> b -> b) -> a -> [T a]
+mkTs = \ f x y -> [T1 f x, T1 f y]
 </ProgramListing>
 
 
@@ -2082,6 +2508,53 @@ rank-2 types as applied to data constructors.
 
 </Sect2>
 
+
+<Sect2 id="hoist">
+<Title>Type synonyms and hoisting
+</Title>
+
+<Para>
+GHC also allows you to write a <Literal>forall</Literal> in a type synonym, thus:
+<ProgramListing>
+  type Discard a = forall b. a -> b -> a
+
+  f :: Discard a
+  f x y = x
+</ProgramListing>
+However, it is often convenient to use these sort of synonyms at the right hand
+end of an arrow, thus:
+<ProgramListing>
+  type Discard a = forall b. a -> b -> a
+
+  g :: Int -> Discard Int
+  g x y z = x+y
+</ProgramListing>
+Simply expanding the type synonym would give
+<ProgramListing>
+  g :: Int -> (forall b. Int -> b -> Int)
+</ProgramListing>
+but GHC "hoists" the <Literal>forall</Literal> to give the isomorphic type
+<ProgramListing>
+  g :: forall b. Int -> Int -> b -> Int
+</ProgramListing>
+In general, the rule is this: <Emphasis>to determine the type specified by any explicit
+user-written type (e.g. in a type signature), GHC expands type synonyms and then repeatedly
+performs the transformation:</Emphasis>
+<ProgramListing>
+  <Emphasis>type1</Emphasis> -> forall a. <Emphasis>type2</Emphasis>
+==>
+  forall a. <Emphasis>type1</Emphasis> -> <Emphasis>type2</Emphasis>
+</ProgramListing>
+(In fact, GHC tries to retain as much synonym information as possible for use in
+error messages, but that is a usability issue.)  This rule applies, of course, whether
+or not the <Literal>forall</Literal> comes from a synonym. For example, here is another
+valid way to write <Literal>g</Literal>'s type signature:
+<ProgramListing>
+  g :: Int -> Int -> forall b. b -> Int
+</ProgramListing>
+</Para>
+</Sect2>
+
 </Sect1>
 
 <Sect1 id="existential-quantification">
@@ -2092,14 +2565,14 @@ rank-2 types as applied to data constructors.
 The idea of using existential quantification in data type declarations
 was suggested by Laufer (I believe, thought doubtless someone will
 correct me), and implemented in Hope+. It's been in Lennart
-Augustsson's <Literal>hbc</Literal> Haskell compiler for several years, and
+Augustsson's <Command>hbc</Command> Haskell compiler for several years, and
 proved very useful.  Here's the idea.  Consider the declaration:
 </Para>
 
 <Para>
 
 <ProgramListing>
-  data Foo = forall a. MkFoo a (a -&#62; Bool)
+  data Foo = forall a. MkFoo a (a -> Bool)
            | Nil
 </ProgramListing>
 
@@ -2112,14 +2585,14 @@ The data type <Literal>Foo</Literal> has two constructors with types:
 <Para>
 
 <ProgramListing>
-  MkFoo :: forall a. a -&#62; (a -&#62; Bool) -&#62; Foo
+  MkFoo :: forall a. a -> (a -> Bool) -> Foo
   Nil   :: Foo
 </ProgramListing>
 
 </Para>
 
 <Para>
-Notice that the type variable <Literal>a</Literal> in the type of <Literal>MkFoo</Literal>
+Notice that the type variable <Literal>a</Literal> in the type of <Function>MkFoo</Function>
 does not appear in the data type itself, which is plain <Literal>Foo</Literal>.
 For example, the following expression is fine:
 </Para>
@@ -2134,14 +2607,14 @@ For example, the following expression is fine:
 
 <Para>
 Here, <Literal>(MkFoo 3 even)</Literal> packages an integer with a function
-<Literal>even</Literal> that maps an integer to <Literal>Bool</Literal>; and <Literal>MkFoo 'c'
-isUpper</Literal> packages a character with a compatible function.  These
+<Function>even</Function> that maps an integer to <Literal>Bool</Literal>; and <Function>MkFoo 'c'
+isUpper</Function> packages a character with a compatible function.  These
 two things are each of type <Literal>Foo</Literal> and can be put in a list.
 </Para>
 
 <Para>
 What can we do with a value of type <Literal>Foo</Literal>?.  In particular,
-what happens when we pattern-match on <Literal>MkFoo</Literal>?
+what happens when we pattern-match on <Function>MkFoo</Function>?
 </Para>
 
 <Para>
@@ -2153,15 +2626,15 @@ what happens when we pattern-match on <Literal>MkFoo</Literal>?
 </Para>
 
 <Para>
-Since all we know about <Literal>val</Literal> and <Literal>fn</Literal> is that they
+Since all we know about <Literal>val</Literal> and <Function>fn</Function> is that they
 are compatible, the only (useful) thing we can do with them is to
-apply <Literal>fn</Literal> to <Literal>val</Literal> to get a boolean.  For example:
+apply <Function>fn</Function> to <Literal>val</Literal> to get a boolean.  For example:
 </Para>
 
 <Para>
 
 <ProgramListing>
-  f :: Foo -&#62; Bool
+  f :: Foo -> Bool
   f (MkFoo val fn) = fn val
 </ProgramListing>
 
@@ -2180,13 +2653,13 @@ quite a bit of object-oriented-like programming this way.
 
 <Para>
 What has this to do with <Emphasis>existential</Emphasis> quantification?
-Simply that <Literal>MkFoo</Literal> has the (nearly) isomorphic type
+Simply that <Function>MkFoo</Function> has the (nearly) isomorphic type
 </Para>
 
 <Para>
 
 <ProgramListing>
-  MkFoo :: (exists a . (a, a -&#62; Bool)) -&#62; Foo
+  MkFoo :: (exists a . (a, a -> Bool)) -> Foo
 </ProgramListing>
 
 </Para>
@@ -2203,15 +2676,15 @@ adding a new existential quantification construct.
 <Title>Type classes</Title>
 
 <Para>
-An easy extension (implemented in <Literal>hbc</Literal>) is to allow
+An easy extension (implemented in <Command>hbc</Command>) is to allow
 arbitrary contexts before the constructor.  For example:
 </Para>
 
 <Para>
 
 <ProgramListing>
-  data Baz = forall a. Eq a =&#62; Baz1 a a
-           | forall b. Show b =&#62; Baz2 b (b -&#62; b)
+data Baz = forall a. Eq a => Baz1 a a
+         | forall b. Show b => Baz2 b (b -> b)
 </ProgramListing>
 
 </Para>
@@ -2223,15 +2696,15 @@ The two constructors have the types you'd expect:
 <Para>
 
 <ProgramListing>
-  Baz1 :: forall a. Eq a =&#62; a -&#62; a -&#62; Baz
-  Baz2 :: forall b. Show b =&#62; b -&#62; (b -&#62; b) -&#62; Baz
+Baz1 :: forall a. Eq a => a -> a -> Baz
+Baz2 :: forall b. Show b => b -> (b -> b) -> Baz
 </ProgramListing>
 
 </Para>
 
 <Para>
-But when pattern matching on <Literal>Baz1</Literal> the matched values can be compared
-for equality, and when pattern matching on <Literal>Baz2</Literal> the first matched
+But when pattern matching on <Function>Baz1</Function> the matched values can be compared
+for equality, and when pattern matching on <Function>Baz2</Function> the first matched
 value can be converted to a string (as well as applying the function to it).
 So this program is legal:
 </Para>
@@ -2239,7 +2712,7 @@ So this program is legal:
 <Para>
 
 <ProgramListing>
-  f :: Baz -&#62; String
+  f :: Baz -> String
   f (Baz1 p q) | p == q    = "Yes"
                | otherwise = "No"
   f (Baz1 v fn)            = show (fn v)
@@ -2249,7 +2722,7 @@ So this program is legal:
 
 <Para>
 Operationally, in a dictionary-passing implementation, the
-constructors <Literal>Baz1</Literal> and <Literal>Baz2</Literal> must store the
+constructors <Function>Baz1</Function> and <Function>Baz2</Function> must store the
 dictionaries for <Literal>Eq</Literal> and <Literal>Show</Literal> respectively, and
 extract it on pattern matching.
 </Para>
@@ -2282,17 +2755,17 @@ the pattern match.  For example, these fragments are incorrect:
 
 
 <ProgramListing>
-  f1 (MkFoo a f) = a
+f1 (MkFoo a f) = a
 </ProgramListing>
 
 
-Here, the type bound by <Literal>MkFoo</Literal> "escapes", because <Literal>a</Literal>
-is the result of <Literal>f1</Literal>.  One way to see why this is wrong is to
-ask what type <Literal>f1</Literal> has:
+Here, the type bound by <Function>MkFoo</Function> "escapes", because <Literal>a</Literal>
+is the result of <Function>f1</Function>.  One way to see why this is wrong is to
+ask what type <Function>f1</Function> has:
 
 
 <ProgramListing>
-  f1 :: Foo -&#62; a             -- Weird!
+  f1 :: Foo -> a             -- Weird!
 </ProgramListing>
 
 
@@ -2301,7 +2774,7 @@ this:
 
 
 <ProgramListing>
-  f1 :: forall a. Foo -&#62; a   -- Wrong!
+  f1 :: forall a. Foo -> a   -- Wrong!
 </ProgramListing>
 
 
@@ -2315,7 +2788,7 @@ The original program is just plain wrong.  Here's another sort of error
 
 It's ok to say <Literal>a==b</Literal> or <Literal>p==q</Literal>, but
 <Literal>a==q</Literal> is wrong because it equates the two distinct types arising
-from the two <Literal>Baz1</Literal> constructors.
+from the two <Function>Baz1</Function> constructors.
 
 
 </Para>
@@ -2355,7 +2828,7 @@ declarations.  So this is illegal:
 
 
 <ProgramListing>
-  newtype T = forall a. Ord a =&#62; MkT a
+  newtype T = forall a. Ord a => MkT a
 </ProgramListing>
 
 
@@ -2383,18 +2856,18 @@ data type with existentially quantified data constructors.
 Reason: in most cases it would not make sense. For example:&num;
 
 <ProgramListing>
-  data T = forall a. MkT [a] deriving( Eq )
+data T = forall a. MkT [a] deriving( Eq )
 </ProgramListing>
 
 To derive <Literal>Eq</Literal> in the standard way we would need to have equality
-between the single component of two <Literal>MkT</Literal> constructors:
+between the single component of two <Function>MkT</Function> constructors:
 
 <ProgramListing>
-  instance Eq T where
-    (MkT a) == (MkT b) = ???
+instance Eq T where
+  (MkT a) == (MkT b) = ???
 </ProgramListing>
 
-But <Literal>a</Literal> and <Literal>b</Literal> have distinct types, and so can't be compared.
+But <VarName>a</VarName> and <VarName>b</VarName> have distinct types, and so can't be compared.
 It's just about possible to imagine examples in which the derived instance
 would make sense, but it seems altogether simpler simply to prohibit such
 declarations.  Define your own instances!
@@ -2422,7 +2895,7 @@ could define a function like the following:
 <Para>
 
 <ProgramListing>
-assert :: Bool -&#62; a -&#62; a
+assert :: Bool -> a -> a
 assert False x = error "assertion failed!"
 assert _     x = x
 </ProgramListing>
@@ -2435,22 +2908,22 @@ an assertion failed, but which and where?
 </Para>
 
 <Para>
-One way out is to define an extended <Literal>assert</Literal> function which also
+One way out is to define an extended <Function>assert</Function> function which also
 takes a descriptive string to include in the error message and
 perhaps combine this with the use of a pre-processor which inserts
-the source location where <Literal>assert</Literal> was used.
+the source location where <Function>assert</Function> was used.
 </Para>
 
 <Para>
 Ghc offers a helping hand here, doing all of this for you. For every
-use of <Literal>assert</Literal> in the user's source:
+use of <Function>assert</Function> in the user's source:
 </Para>
 
 <Para>
 
 <ProgramListing>
-kelvinToC :: Double -&#62; Double
-kelvinToC k = assert (k &amp;gt;= 0.0) (k+273.15)
+kelvinToC :: Double -> Double
+kelvinToC k = assert (k &gt;= 0.0) (k+273.15)
 </ProgramListing>
 
 </Para>
@@ -2463,27 +2936,28 @@ assertion was made,
 <Para>
 
 <ProgramListing>
-assert pred val ==&#62; assertError "Main.hs|15" pred val
+assert pred val ==> assertError "Main.hs|15" pred val
 </ProgramListing>
 
 </Para>
 
 <Para>
 The rewrite is only performed by the compiler when it spots
-applications of <Literal>Exception.assert</Literal>, so you can still define and
-use your own versions of <Literal>assert</Literal>, should you so wish. If not,
-import <Literal>Exception</Literal> to make use <Literal>assert</Literal> in your code.
+applications of <Function>Exception.assert</Function>, so you can still define and
+use your own versions of <Function>assert</Function>, should you so wish. If not,
+import <Literal>Exception</Literal> to make use <Function>assert</Function> in your code.
 </Para>
 
 <Para>
 To have the compiler ignore uses of assert, use the compiler option
-<Literal>-fignore-asserts</Literal>. <IndexTerm><Primary>-fignore-asserts option</Primary></IndexTerm> That is,
+<Option>-fignore-asserts</Option>. <IndexTerm><Primary>-fignore-asserts option</Primary></IndexTerm> That is,
 expressions of the form <Literal>assert pred e</Literal> will be rewritten to <Literal>e</Literal>.
 </Para>
 
 <Para>
 Assertion failures can be caught, see the documentation for the
-Hugs/GHC Exception library for information of how.
+<literal>Exception</literal> library (<xref linkend="sec-Exception">)
+for the details.
 </Para>
 
 </Sect1>
@@ -2509,21 +2983,21 @@ f (xs::[a]) = ys ++ ys
 </Para>
 
 <Para>
-The pattern <Literal>(xs::[a])</Literal> includes a type signature for <Literal>xs</Literal>.
+The pattern <Literal>(xs::[a])</Literal> includes a type signature for <VarName>xs</VarName>.
 This brings the type variable <Literal>a</Literal> into scope; it scopes over
-all the patterns and right hand sides for this equation for <Literal>f</Literal>.
-In particular, it is in scope at the type signature for <Literal>y</Literal>.
+all the patterns and right hand sides for this equation for <Function>f</Function>.
+In particular, it is in scope at the type signature for <VarName>y</VarName>.
 </Para>
 
 <Para>
-At ordinary type signatures, such as that for <Literal>ys</Literal>, any type variables
+At ordinary type signatures, such as that for <VarName>ys</VarName>, any type variables
 mentioned in the type signature <Emphasis>that are not in scope</Emphasis> are
 implicitly universally quantified.  (If there are no type variables in
 scope, all type variables mentioned in the signature are universally
-quantified, which is just as in Haskell 98.)  In this case, since <Literal>a</Literal>
-is in scope, it is not universally quantified, so the type of <Literal>ys</Literal> is
-the same as that of <Literal>xs</Literal>.  In Haskell 98 it is not possible to declare
-a type for <Literal>ys</Literal>; a major benefit of scoped type variables is that
+quantified, which is just as in Haskell 98.)  In this case, since <VarName>a</VarName>
+is in scope, it is not universally quantified, so the type of <VarName>ys</VarName> is
+the same as that of <VarName>xs</VarName>.  In Haskell 98 it is not possible to declare
+a type for <VarName>ys</VarName>; a major benefit of scoped type variables is that
 it becomes possible to do so.
 </Para>
 
@@ -2578,12 +3052,12 @@ into scope (except in the type signature itself!). So this is illegal:
 
 
 <ProgramListing>
-  f :: a -&#62; a
+  f :: a -> a
   f x = x::a
 </ProgramListing>
 
 
-It's illegal because <Literal>a</Literal> is not in scope in the body of <Literal>f</Literal>,
+It's illegal because <VarName>a</VarName> is not in scope in the body of <Function>f</Function>,
 so the ordinary signature <Literal>x::a</Literal> is equivalent to <Literal>x::forall a.a</Literal>;
 and that is an incorrect typing.
 
@@ -2608,7 +3082,7 @@ scope over the methods defined in the <Literal>where</Literal> part.  For exampl
 
 <ProgramListing>
   class C a where
-    op :: [a] -&#62; a
+    op :: [a] -> a
 
     op xs = let ys::[a]
                 ys = reverse xs
@@ -2642,7 +3116,7 @@ no scoping associated with the names of the type variables in a separate type si
 
 
 <ProgramListing>
-   f :: [a] -&#62; [a]
+   f :: [a] -> [a]
    f (xs::[b]) = reverse xs
 </ProgramListing>
 
@@ -2695,7 +3169,7 @@ For example, the following all fail to type check:
   k (x::a) True    = ...        -- a unifies with Int
   k (x::Int) False = ...
 
-  w :: [b] -&#62; [b]
+  w :: [b] -> [b]
   w (x::a) = x                  -- a unifies with [b]
 </ProgramListing>
 
@@ -2742,15 +3216,15 @@ thus:
 </ProgramListing>
 
 
-The final <Literal>":: [a]"</Literal> after all the patterns gives a signature to the
+The final <Literal>:: [a]</Literal> after all the patterns gives a signature to the
 result type.  Sometimes this is the only way of naming the type variable
 you want:
 
 
 <ProgramListing>
-  f :: Int -&#62; [a] -&#62; [a]
-  f n :: ([a] -&#62; [a]) = let g (x::a, y::a) = (y,x)
-                        in \xs -&#62; map g (reverse xs `zip` xs)
+  f :: Int -> [a] -> [a]
+  f n :: ([a] -> [a]) = let g (x::a, y::a) = (y,x)
+                        in \xs -> map g (reverse xs `zip` xs)
 </ProgramListing>
 
 
@@ -2795,7 +3269,7 @@ in lambda abstractions:
 
 
 <ProgramListing>
-  (\ (x::a, y) :: a -&#62; x)
+  (\ (x::a, y) :: a -> x)
 </ProgramListing>
 
 
@@ -2806,13 +3280,13 @@ For example:
 
 <ProgramListing>
   f1 (x::c) = f1 x      -- ok
-  f2 = \(x::c) -&#62; f2 x  -- not ok
+  f2 = \(x::c) -> f2 x  -- not ok
 </ProgramListing>
 
 
-Here, <Literal>f1</Literal> is OK, but <Literal>f2</Literal> is not, because <Literal>c</Literal> gets unified
+Here, <Function>f1</Function> is OK, but <Function>f2</Function> is not, because <VarName>c</VarName> gets unified
 with a type variable free in the environment, in this
-case, the type of <Literal>f2</Literal>, which is in the environment when
+case, the type of <Function>f2</Function>, which is in the environment when
 the lambda abstraction is checked.
 
 </Para>
@@ -2825,7 +3299,7 @@ in <Literal>case</Literal> expressions:
 
 
 <ProgramListing>
-  case e of { (x::a, y) :: a -&#62; x }
+  case e of { (x::a, y) :: a -> x }
 </ProgramListing>
 
 
@@ -2836,7 +3310,7 @@ Thus this is OK:
 
 
 <ProgramListing>
-  case (True,False) of { (x::a, y) -&#62; x }
+  case (True,False) of { (x::a, y) -> x }
 </ProgramListing>
 
 
@@ -2846,7 +3320,7 @@ also OK to say:
 
 
 <ProgramListing>
-  case (True,False) of { (x::Bool, y) -&#62; x }
+  case (True,False) of { (x::Bool, y) -> x }
 </ProgramListing>
 
 
@@ -2855,14 +3329,14 @@ also OK to say:
 <ListItem>
 
 <Para>
-To avoid ambiguity, the type after the ``<Literal>::</Literal>'' in a result
+To avoid ambiguity, the type after the &ldquo;<Literal>::</Literal>&rdquo; in a result
 pattern signature on a lambda or <Literal>case</Literal> must be atomic (i.e. a single
 token or a parenthesised type of some sort).  To see why,
 consider how one would parse this:
 
 
 <ProgramListing>
-  \ x :: a -&#62; b -&#62; x
+  \ x :: a -> b -> x
 </ProgramListing>
 
 
@@ -2896,7 +3370,7 @@ though it binds a type variable:
 
 
 <ProgramListing>
-  f :: (b-&#62;b) = \(x::b) -&#62; x
+  f :: (b->b) = \(x::b) -> x
 </ProgramListing>
 
 
@@ -2912,14 +3386,14 @@ restriction.  Thus:
 <Para>
 
 <ProgramListing>
-  g :: a -&#62; a -&#62; Bool = \x y. x==y
+  g :: a -> a -> Bool = \x y. x==y
 </ProgramListing>
 
 </Para>
 
 <Para>
-Here <Literal>g</Literal> has type <Literal>forall a. Eq a =&gt; a -&gt; a -&gt; Bool</Literal>, just as if
-<Literal>g</Literal> had a separate type signature.  Lacking a type signature, <Literal>g</Literal>
+Here <Function>g</Function> has type <Literal>forall a. Eq a =&gt; a -&gt; a -&gt; Bool</Literal>, just as if
+<Function>g</Function> had a separate type signature.  Lacking a type signature, <Function>g</Function>
 would get a monomorphic type.
 </Para>
 
@@ -2941,7 +3415,7 @@ For example:
 <ProgramListing>
   data T = forall a. MkT [a]
 
-  f :: T -&#62; T
+  f :: T -> T
   f (MkT [t::a]) = MkT t3
                  where
                    t3::[a] = [t,t,t]
@@ -2976,8 +3450,8 @@ but they might affect the efficiency of the generated code.
 <IndexTerm><Primary>pragma, INLINE</Primary></IndexTerm></Title>
 
 <Para>
-GHC (with <Literal>-O</Literal>, as always) tries to inline (or ``unfold'')
-functions/values that are ``small enough,'' thus avoiding the call
+GHC (with <Option>-O</Option>, as always) tries to inline (or &ldquo;unfold&rdquo;)
+functions/values that are &ldquo;small enough,&rdquo; thus avoiding the call
 overhead and possibly exposing other more-wonderful optimisations.
 </Para>
 
@@ -2987,7 +3461,7 @@ interface files.
 </Para>
 
 <Para>
-Normally, if GHC decides a function is ``too expensive'' to inline, it
+Normally, if GHC decides a function is &ldquo;too expensive&rdquo; to inline, it
 will not do so, nor will it export that unfolding for other modules to
 use.
 </Para>
@@ -2997,7 +3471,7 @@ The sledgehammer you can bring to bear is the
 <Literal>INLINE</Literal><IndexTerm><Primary>INLINE pragma</Primary></IndexTerm> pragma, used thusly:
 
 <ProgramListing>
-key_function :: Int -&#62; String -&#62; (Bool, Double)
+key_function :: Int -> String -> (Bool, Double)
 
 #ifdef __GLASGOW_HASKELL__
 {-# INLINE key_function #-}
@@ -3010,7 +3484,7 @@ to stick the code through HBC&mdash;it doesn't like <Literal>INLINE</Literal> pr
 
 <Para>
 The major effect of an <Literal>INLINE</Literal> pragma is to declare a function's
-``cost'' to be very low.  The normal unfolding machinery will then be
+&ldquo;cost&rdquo; to be very low.  The normal unfolding machinery will then be
 very keen to inline it.
 </Para>
 
@@ -3071,7 +3545,7 @@ types.  Thus, if you have an overloaded function:
 <Para>
 
 <ProgramListing>
-hammeredLookup :: Ord key =&#62; [(key, value)] -&#62; key -&#62; value
+hammeredLookup :: Ord key => [(key, value)] -> key -> value
 </ProgramListing>
 
 </Para>
@@ -3081,7 +3555,7 @@ If it is heavily used on lists with <Literal>Widget</Literal> keys, you could
 specialise it as follows:
 
 <ProgramListing>
-{-# SPECIALIZE hammeredLookup :: [(Widget, value)] -&#62; Widget -&#62; value #-}
+{-# SPECIALIZE hammeredLookup :: [(Widget, value)] -> Widget -> value #-}
 </ProgramListing>
 
 </Para>
@@ -3094,8 +3568,8 @@ the specialised value, by adding <Literal>= blah</Literal>, as in:
 {-# SPECIALIZE hammeredLookup :: ...as before... = blah #-}
 </ProgramListing>
 
-It's <Emphasis>Your Responsibility</Emphasis> to make sure that <Literal>blah</Literal> really
-behaves as a specialised version of <Literal>hammeredLookup</Literal>!!!
+It's <Emphasis>Your Responsibility</Emphasis> to make sure that <Function>blah</Function> really
+behaves as a specialised version of <Function>hammeredLookup</Function>!!!
 </Para>
 
 <Para>
@@ -3106,14 +3580,14 @@ NOTE: the <Literal>=blah</Literal> feature isn't implemented in GHC 4.xx.
 An example in which the <Literal>= blah</Literal> form will Win Big:
 
 <ProgramListing>
-toDouble :: Real a =&#62; a -&#62; Double
+toDouble :: Real a => a -> Double
 toDouble = fromRational . toRational
 
-{-# SPECIALIZE toDouble :: Int -&#62; Double = i2d #-}
+{-# SPECIALIZE toDouble :: Int -> Double = i2d #-}
 i2d (I# i) = D# (int2Double# i) -- uses Glasgow prim-op directly
 </ProgramListing>
 
-The <Literal>i2d</Literal> function is virtually one machine instruction; the
+The <Function>i2d</Function> function is virtually one machine instruction; the
 default conversion&mdash;via an intermediate <Literal>Rational</Literal>&mdash;is obscenely
 expensive by comparison.
 </Para>
@@ -3140,7 +3614,7 @@ signature could be put.
 Same idea, except for instance declarations.  For example:
 
 <ProgramListing>
-instance (Eq a) =&#62; Eq (Foo a) where { ... usual stuff ... }
+instance (Eq a) => Eq (Foo a) where { ... usual stuff ... }
 
 {-# SPECIALIZE instance Eq (Foo [(Int, Bar)] #-}
 </ProgramListing>
@@ -3174,7 +3648,7 @@ number and filename of the original code; for example
 </Para>
 
 <Para>
-if you'd generated the current file from something called <Literal>Foo.vhs</Literal>
+if you'd generated the current file from something called <Filename>Foo.vhs</Filename>
 and this line corresponds to line 42 in the original.  GHC will adjust
 its error messages to refer to the line/file named in the <Literal>LINE</Literal>
 pragma.
@@ -3248,8 +3722,8 @@ enclosing definitions.
 <ListItem>
 
 <Para>
- Each variable mentioned in a rule must either be in scope (e.g. <Literal>map</Literal>),
-or bound by the <Literal>forall</Literal> (e.g. <Literal>f</Literal>, <Literal>g</Literal>, <Literal>xs</Literal>).  The variables bound by
+ Each variable mentioned in a rule must either be in scope (e.g. <Function>map</Function>),
+or bound by the <Literal>forall</Literal> (e.g. <Function>f</Function>, <Function>g</Function>, <Function>xs</Function>).  The variables bound by
 the <Literal>forall</Literal> are called the <Emphasis>pattern</Emphasis> variables.  They are separated
 by spaces, just like in a type <Literal>forall</Literal>.
 </Para>
@@ -3262,23 +3736,23 @@ If the type of the pattern variable is polymorphic, it <Emphasis>must</Emphasis>
 For example, here is the <Literal>foldr/build</Literal> rule:
 
 <ProgramListing>
-  "fold/build"  forall k z (g::forall b. (a-&#62;b-&#62;b) -&#62; b -&#62; b) .
-                foldr k z (build g) = g k z
+"fold/build"  forall k z (g::forall b. (a->b->b) -> b -> b) .
+              foldr k z (build g) = g k z
 </ProgramListing>
 
-Since <Literal>g</Literal> has a polymorphic type, it must have a type signature.
+Since <Function>g</Function> has a polymorphic type, it must have a type signature.
 
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- The left hand side of a rule must consist of a top-level variable applied
+The left hand side of a rule must consist of a top-level variable applied
 to arbitrary expressions.  For example, this is <Emphasis>not</Emphasis> OK:
 
 <ProgramListing>
-  "wrong1"   forall e1 e2.  case True of { True -&#62; e1; False -&#62; e2 } = e1
-  "wrong2"   forall f.      f True = True
+"wrong1"   forall e1 e2.  case True of { True -> e1; False -> e2 } = e1
+"wrong2"   forall f.      f True = True
 </ProgramListing>
 
 In <Literal>"wrong1"</Literal>, the LHS is not an application; in <Literal>"wrong1"</Literal>, the LHS has a pattern variable
@@ -3315,12 +3789,11 @@ From a semantic point of view:
 <ListItem>
 
 <Para>
- Rules are only applied if you use the <Literal>-O</Literal> flag.
-
+Rules are only applied if you use the <Option>-O</Option> flag.
 </Para>
 </ListItem>
-<ListItem>
 
+<ListItem>
 <Para>
  Rules are regarded as left-to-right rewrite rules.
 When GHC finds an expression that is a substitution instance of the LHS
@@ -3398,8 +3871,8 @@ For example, consider:
 </ProgramListing>
 
 The expression <Literal>s (t xs)</Literal> does not match the rule <Literal>"map/map"</Literal>, but GHC
-will substitute for <Literal>s</Literal> and <Literal>t</Literal>, giving an expression which does match.
-If <Literal>s</Literal> or <Literal>t</Literal> was (a) used more than once, and (b) large or a redex, then it would
+will substitute for <VarName>s</VarName> and <VarName>t</VarName>, giving an expression which does match.
+If <VarName>s</VarName> or <VarName>t</VarName> was (a) used more than once, and (b) large or a redex, then it would
 not be substituted, and the rule would not fire.
 
 </Para>
@@ -3421,20 +3894,20 @@ It will only match something written with explicit use of ".".
 Well, not quite.  It <Emphasis>will</Emphasis> match the expression
 
 <ProgramListing>
-        wibble f g xs
+wibble f g xs
 </ProgramListing>
 
-where <Literal>wibble</Literal> is defined:
+where <Function>wibble</Function> is defined:
 
 <ProgramListing>
-        wibble f g = map f . map g
+wibble f g = map f . map g
 </ProgramListing>
 
-because <Literal>wibble</Literal> will be inlined (it's small).
+because <Function>wibble</Function> will be inlined (it's small).
 
 Later on in compilation, GHC starts inlining even things on the
 LHS of rules, but still leaves the rules enabled.  This inlining
-policy is controlled by the per-simplification-pass flag <Literal>-finline-phase</Literal>n.
+policy is controlled by the per-simplification-pass flag <Option>-finline-phase</Option><Emphasis>n</Emphasis>.
 
 </Para>
 </ListItem>
@@ -3495,31 +3968,31 @@ The following are good producers:
 <ListItem>
 
 <Para>
- <Literal>++</Literal>
+ <Function>++</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>map</Literal>
+ <Function>map</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>filter</Literal>
+ <Function>filter</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>iterate</Literal>, <Literal>repeat</Literal>
+ <Function>iterate</Function>, <Function>repeat</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>zip</Literal>, <Literal>zipWith</Literal>
+ <Function>zip</Function>, <Function>zipWith</Function>
 </Para>
 </ListItem>
 
@@ -3540,86 +4013,86 @@ The following are good consumers:
 <ListItem>
 
 <Para>
- <Literal>array</Literal> (on its second argument)
+ <Function>array</Function> (on its second argument)
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>length</Literal>
+ <Function>length</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>++</Literal> (on its first argument)
+ <Function>++</Function> (on its first argument)
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>map</Literal>
+ <Function>map</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>filter</Literal>
+ <Function>filter</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>concat</Literal>
+ <Function>concat</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>unzip</Literal>, <Literal>unzip2</Literal>, <Literal>unzip3</Literal>, <Literal>unzip4</Literal>
+ <Function>unzip</Function>, <Function>unzip2</Function>, <Function>unzip3</Function>, <Function>unzip4</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>zip</Literal>, <Literal>zipWith</Literal> (but on one argument only; if both are good producers, <Literal>zip</Literal>
+ <Function>zip</Function>, <Function>zipWith</Function> (but on one argument only; if both are good producers, <Function>zip</Function>
 will fuse with one but not the other)
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>partition</Literal>
+ <Function>partition</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>head</Literal>
+ <Function>head</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>and</Literal>, <Literal>or</Literal>, <Literal>any</Literal>, <Literal>all</Literal>
+ <Function>and</Function>, <Function>or</Function>, <Function>any</Function>, <Function>all</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>sequence&lowbar;</Literal>
+ <Function>sequence&lowbar;</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>msum</Literal>
+ <Function>msum</Function>
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- <Literal>sortBy</Literal>
+ <Function>sortBy</Function>
 </Para>
 </ListItem>
 
@@ -3631,7 +4104,7 @@ will fuse with one but not the other)
 So, for example, the following should generate no intermediate lists:
 
 <ProgramListing>
-        array (1,10) [(i,i*i) | i &#60;- map (+ 1) [0..9]]
+array (1,10) [(i,i*i) | i &#60;- map (+ 1) [0..9]]
 </ProgramListing>
 
 </Para>
@@ -3657,13 +4130,13 @@ Rewrite rules can be used to get the same effect as a feature
 present in earlier version of GHC:
 
 <ProgramListing>
-  {-# SPECIALIZE fromIntegral :: Int8 -&#62; Int16 = int8ToInt16 #-}
+  {-# SPECIALIZE fromIntegral :: Int8 -> Int16 = int8ToInt16 #-}
 </ProgramListing>
 
-This told GHC to use <Literal>int8ToInt16</Literal> instead of <Literal>fromIntegral</Literal> whenever
+This told GHC to use <Function>int8ToInt16</Function> instead of <Function>fromIntegral</Function> whenever
 the latter was called with type <Literal>Int8 -&gt; Int16</Literal>.  That is, rather than
-specialising the original definition of <Literal>fromIntegral</Literal> the programmer is
-promising that it is safe to use <Literal>int8ToInt16</Literal> instead.
+specialising the original definition of <Function>fromIntegral</Function> the programmer is
+promising that it is safe to use <Function>int8ToInt16</Function> instead.
 </Para>
 
 <Para>
@@ -3671,18 +4144,18 @@ This feature is no longer in GHC.  But rewrite rules let you do the
 same thing:
 
 <ProgramListing>
-  {-# RULES
-    "fromIntegral/Int8/Int16" fromIntegral = int8ToInt16
-  #-}
+{-# RULES
+  "fromIntegral/Int8/Int16" fromIntegral = int8ToInt16
+#-}
 </ProgramListing>
 
-This slightly odd-looking rule instructs GHC to replace <Literal>fromIntegral</Literal>
-by <Literal>int8ToInt16</Literal> <Emphasis>whenever the types match</Emphasis>.  Speaking more operationally,
+This slightly odd-looking rule instructs GHC to replace <Function>fromIntegral</Function>
+by <Function>int8ToInt16</Function> <Emphasis>whenever the types match</Emphasis>.  Speaking more operationally,
 GHC adds the type and dictionary applications to get the typed rule
 
 <ProgramListing>
-        forall (d1::Integral Int8) (d2::Num Int16) .
-                fromIntegral Int8 Int16 d1 d2 = int8ToInt16
+forall (d1::Integral Int8) (d2::Num Int16) .
+        fromIntegral Int8 Int16 d1 d2 = int8ToInt16
 </ProgramListing>
 
 What is more,
@@ -3702,29 +4175,29 @@ have an original definition available to specialise).
 <ListItem>
 
 <Para>
- Use <Literal>-ddump-rules</Literal> to see what transformation rules GHC is using.
+ Use <Option>-ddump-rules</Option> to see what transformation rules GHC is using.
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- Use <Literal>-ddump-simpl-stats</Literal> to see what rules are being fired.
-If you add <Literal>-dppr-debug</Literal> you get a more detailed listing.
+ Use <Option>-ddump-simpl-stats</Option> to see what rules are being fired.
+If you add <Option>-dppr-debug</Option> you get a more detailed listing.
 </Para>
 </ListItem>
 <ListItem>
 
 <Para>
- The defintion of (say) <Literal>build</Literal> in <Literal>PrelBase.lhs</Literal> looks llike this:
+ The defintion of (say) <Function>build</Function> in <FileName>PrelBase.lhs</FileName> looks llike this:
 
 <ProgramListing>
-        build   :: forall a. (forall b. (a -&#62; b -&#62; b) -&#62; b -&#62; b) -&#62; [a]
+        build   :: forall a. (forall b. (a -> b -> b) -> b -> b) -> [a]
         {-# INLINE build #-}
         build g = g (:) []
 </ProgramListing>
 
 Notice the <Literal>INLINE</Literal>!  That prevents <Literal>(:)</Literal> from being inlined when compiling
-<Literal>PrelBase</Literal>, so that an importing module will ``see'' the <Literal>(:)</Literal>, and can
+<Literal>PrelBase</Literal>, so that an importing module will &ldquo;see&rdquo; the <Literal>(:)</Literal>, and can
 match it on the LHS of a rule.  <Literal>INLINE</Literal> prevents any inlining happening
 in the RHS of the <Literal>INLINE</Literal> thing.  I regret the delicacy of this.
 
@@ -3733,9 +4206,9 @@ in the RHS of the <Literal>INLINE</Literal> thing.  I regret the delicacy of thi
 <ListItem>
 
 <Para>
- In <Literal>ghc/lib/std/PrelBase.lhs</Literal> look at the rules for <Literal>map</Literal> to
+ In <Filename>ghc/lib/std/PrelBase.lhs</Filename> look at the rules for <Function>map</Function> to
 see how to write rules that will do fusion and yet give an efficient
-program even if fusion doesn't happen.  More rules in <Literal>PrelList.lhs</Literal>.
+program even if fusion doesn't happen.  More rules in <Filename>PrelList.lhs</Filename>.
 </Para>
 </ListItem>
 
@@ -3746,3 +4219,10 @@ program even if fusion doesn't happen.  More rules in <Literal>PrelList.lhs</Lit
 </Sect2>
 
 </Sect1>
+
+<!-- Emacs stuff:
+     ;;; Local Variables: ***
+     ;;; mode: sgml ***
+     ;;; sgml-parent-document: ("users_guide.sgml" "book" "chapter" "sect1") ***
+     ;;; End: ***
+ -->