-There are two coercion functions for <literal>Float#</literal>/<literal>Double#</literal>:
-</para>
-
-<para>
-
-<programlisting>
-float2Double# :: Float# -> Double#
-double2Float# :: Double# -> Float#
-</programlisting>
-
-<indexterm><primary><literal>float2Double#</literal></primary></indexterm>
-<indexterm><primary><literal>double2Float#</literal></primary></indexterm>
-</para>
-
-<para>
-The primitive version of <function>decodeDouble</function>
-(<function>encodeDouble</function> is implemented as an external C
-function):
-</para>
-
-<para>
-
-<programlisting>
-decodeDouble# :: Double# -> PrelNum.ReturnIntAndGMP
-</programlisting>
-
-<indexterm><primary><literal>encodeDouble#</literal></primary></indexterm>
-<indexterm><primary><literal>decodeDouble#</literal></primary></indexterm>
-</para>
-
-<para>
-(And the same for <literal>Float#</literal>s.)
-</para>
-
-</sect2>
-
-<sect2 id="integer-operations">
-<title>Operations on/for <literal>Integers</literal> (interface to GMP)
-</title>
-
-<para>
-<indexterm><primary>arbitrary precision integers</primary></indexterm>
-<indexterm><primary>Integer, operations on</primary></indexterm>
-</para>
-
-<para>
-We implement <literal>Integers</literal> (arbitrary-precision
-integers) using the GNU multiple-precision (GMP) package (version
-2.0.2).
-</para>
-
-<para>
-The data type for <literal>Integer</literal> is either a small
-integer, represented by an <literal>Int</literal>, or a large integer
-represented using the pieces required by GMP's
-<literal>MP_INT</literal> in <filename>gmp.h</filename> (see
-<filename>gmp.info</filename> in
-<filename>ghc/includes/runtime/gmp</filename>). It comes out as:
-</para>
-
-<para>
-
-<programlisting>
-data Integer = S# Int# -- small integers
- | J# Int# ByteArray# -- large integers
-</programlisting>
-
-<indexterm><primary>Integer type</primary></indexterm> The primitive
-ops to support large <literal>Integers</literal> use the
-“pieces” of the representation, and are as follows:
-</para>
-
-<para>
-
-<programlisting>
-negateInteger# :: Int# -> ByteArray# -> Integer
-
-{plus,minus,times}Integer#, gcdInteger#,
- quotInteger#, remInteger#, divExactInteger#
- :: Int# -> ByteArray#
- -> Int# -> ByteArray#
- -> (# Int#, ByteArray# #)
-
-cmpInteger#
- :: Int# -> ByteArray#
- -> Int# -> ByteArray#
- -> Int# -- -1 for <; 0 for ==; +1 for >
-
-cmpIntegerInt#
- :: Int# -> ByteArray#
- -> Int#
- -> Int# -- -1 for <; 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#</literal></primary></indexterm>
-<indexterm><primary><literal>plusInteger#</literal></primary></indexterm>
-<indexterm><primary><literal>minusInteger#</literal></primary></indexterm>
-<indexterm><primary><literal>timesInteger#</literal></primary></indexterm>
-<indexterm><primary><literal>quotInteger#</literal></primary></indexterm>
-<indexterm><primary><literal>remInteger#</literal></primary></indexterm>
-<indexterm><primary><literal>gcdInteger#</literal></primary></indexterm>
-<indexterm><primary><literal>gcdIntegerInt#</literal></primary></indexterm>
-<indexterm><primary><literal>divExactInteger#</literal></primary></indexterm>
-<indexterm><primary><literal>cmpInteger#</literal></primary></indexterm>
-<indexterm><primary><literal>divModInteger#</literal></primary></indexterm>
-<indexterm><primary><literal>quotRemInteger#</literal></primary></indexterm>
-<indexterm><primary><literal>integer2Int#</literal></primary></indexterm>
-<indexterm><primary><literal>int2Integer#</literal></primary></indexterm>
-<indexterm><primary><literal>word2Integer#</literal></primary></indexterm>
-<indexterm><primary><literal>addr2Integer#</literal></primary></indexterm>
-</para>
-
-</sect2>
-
-<sect2>
-<title>Words and addresses</title>
-
-<para>
-<indexterm><primary>word, primitive type</primary></indexterm>
-<indexterm><primary>address, primitive type</primary></indexterm>
-<indexterm><primary>unsigned integer, primitive type</primary></indexterm>
-<indexterm><primary>pointer, primitive type</primary></indexterm>
-</para>
-
-<para>
-A <literal>Word#</literal> is used for bit-twiddling operations.
-It is the same size as an <literal>Int#</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#</literal></primary></indexterm>
-<indexterm><primary><literal>Addr#</literal></primary></indexterm>
-</para>
-
-<para>
-<literal>Word#</literal>s and <literal>Addr#</literal>s have
-the usual comparison operations. Other
-unboxed-<literal>Word</literal> ops (bit-twiddling and coercions):
-</para>
-
-<para>
-
-<programlisting>
-{gt,ge,eq,ne,lt,le}Word# :: Word# -> Word# -> Bool
-
-and#, or#, xor# :: Word# -> Word# -> Word#
- -- standard bit ops.
-
-quotWord#, remWord# :: Word# -> Word# -> Word#
- -- word (i.e. unsigned) versions are different from int
- -- versions, so we have to provide these explicitly.
-
-not# :: Word# -> Word#
-
-shiftL#, shiftRL# :: Word# -> Int# -> Word#
- -- shift left, right logical
-
-int2Word# :: Int# -> Word# -- just a cast, really
-word2Int# :: Word# -> Int#
-</programlisting>
-
-<indexterm><primary>bit operations, Word and Addr</primary></indexterm>
-<indexterm><primary><literal>gtWord#</literal></primary></indexterm>
-<indexterm><primary><literal>geWord#</literal></primary></indexterm>
-<indexterm><primary><literal>eqWord#</literal></primary></indexterm>
-<indexterm><primary><literal>neWord#</literal></primary></indexterm>
-<indexterm><primary><literal>ltWord#</literal></primary></indexterm>
-<indexterm><primary><literal>leWord#</literal></primary></indexterm>
-<indexterm><primary><literal>and#</literal></primary></indexterm>
-<indexterm><primary><literal>or#</literal></primary></indexterm>
-<indexterm><primary><literal>xor#</literal></primary></indexterm>
-<indexterm><primary><literal>not#</literal></primary></indexterm>
-<indexterm><primary><literal>quotWord#</literal></primary></indexterm>
-<indexterm><primary><literal>remWord#</literal></primary></indexterm>
-<indexterm><primary><literal>shiftL#</literal></primary></indexterm>
-<indexterm><primary><literal>shiftRA#</literal></primary></indexterm>
-<indexterm><primary><literal>shiftRL#</literal></primary></indexterm>
-<indexterm><primary><literal>int2Word#</literal></primary></indexterm>
-<indexterm><primary><literal>word2Int#</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#</literal></primary></indexterm>
-<indexterm><primary><literal>geAddr#</literal></primary></indexterm>
-<indexterm><primary><literal>eqAddr#</literal></primary></indexterm>
-<indexterm><primary><literal>neAddr#</literal></primary></indexterm>
-<indexterm><primary><literal>ltAddr#</literal></primary></indexterm>
-<indexterm><primary><literal>leAddr#</literal></primary></indexterm>
-<indexterm><primary><literal>int2Addr#</literal></primary></indexterm>
-<indexterm><primary><literal>addr2Int#</literal></primary></indexterm>
-<indexterm><primary><literal>addr2Integer#</literal></primary></indexterm>
-</para>
-
-<para>
-The casts between <literal>Int#</literal>,
-<literal>Word#</literal> and <literal>Addr#</literal>
-correspond to null operations at the machine level, but are required
-to keep the Haskell type checker happy.
-</para>
-
-<para>
-Operations for indexing off of C pointers
-(<literal>Addr#</literal>s) to snatch values are listed under
-“arrays”.
-</para>
-
-</sect2>
-
-<sect2>
-<title>Arrays</title>
-
-<para>
-<indexterm><primary>arrays, primitive</primary></indexterm>
-</para>
-
-<para>
-The type <literal>Array# elt</literal> is the type of primitive,
-unpointed arrays of values of type <literal>elt</literal>.
-</para>
-
-<para>
-
-<programlisting>
-type Array# elt
-</programlisting>
-
-<indexterm><primary><literal>Array#</literal></primary></indexterm>
-</para>
-
-<para>
-<literal>Array#</literal> is more primitive than a Haskell
-array—indeed, the Haskell <literal>Array</literal> interface is
-implemented using <literal>Array#</literal>—in that an
-<literal>Array#</literal> is indexed only by
-<literal>Int#</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—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#</literal> are themselves boxed.
-</para>
-
-<para>
-The type <literal>ByteArray#</literal> is similar to
-<literal>Array#</literal>, except that it contains just a string
-of (non-pointer) bytes.
-</para>
-
-<para>
-
-<programlisting>
-type ByteArray#
-</programlisting>
-
-<indexterm><primary><literal>ByteArray#</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#</literal>
-is deliberately a bit vague about the type of its components.
-Operations are provided to extract values of type
-<literal>Char#</literal>, <literal>Int#</literal>,
-<literal>Float#</literal>, <literal>Double#</literal>, and
-<literal>Addr#</literal> from arbitrary offsets within a
-<literal>ByteArray#</literal>. (For type
-<literal>Foo#</literal>, the $i$th offset gets you the $i$th
-<literal>Foo#</literal>, not the <literal>Foo#</literal> at
-byte-position $i$. Mumble.) (If you want a
-<literal>Word#</literal>, grab an <literal>Int#</literal>,
-then coerce it.)
-</para>
-
-<para>
-Lastly, we have static byte-arrays, of type
-<literal>Addr#</literal> [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#</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#</literal>, <literal>Addr#</literal>, and
-<literal>MutableByteArray#</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#</literal> to contain a mixture of values of different
-type, which is often needed when preparing data for and unpicking
-results from C. (Umm…not true of indices…WDP 95/09)
-</para>
-
-<para>
-<emphasis>Should we provide some <literal>sizeOfDouble#</literal> constants?</emphasis>
-</para>
-
-<para>
-Out-of-range errors on indexing should be caught by the code which
-uses the primitive operation; the primitive operations themselves do
-<emphasis>not</emphasis> check for out-of-range indexes. The intention is that the
-primitive ops compile to one machine instruction or thereabouts.
-</para>
-
-<para>
-We use the terms “reading” and “writing” to refer to accessing
-<emphasis>mutable</emphasis> arrays (see <xref LinkEnd="sect-mutable">), and
-“indexing” to refer to reading a value from an <emphasis>immutable</emphasis>
-array.
-</para>
-
-<para>
-Immutable byte arrays are straightforward to index (all indices in bytes):
-
-<programlisting>
-indexCharArray# :: ByteArray# -> Int# -> Char#
-indexIntArray# :: ByteArray# -> Int# -> Int#
-indexAddrArray# :: ByteArray# -> Int# -> Addr#
-indexFloatArray# :: ByteArray# -> Int# -> Float#
-indexDoubleArray# :: ByteArray# -> Int# -> Double#
-
-indexCharOffAddr# :: Addr# -> Int# -> Char#
-indexIntOffAddr# :: Addr# -> Int# -> Int#
-indexFloatOffAddr# :: Addr# -> Int# -> Float#
-indexDoubleOffAddr# :: Addr# -> Int# -> Double#
-indexAddrOffAddr# :: Addr# -> Int# -> Addr#
- -- Get an Addr# from an Addr# offset
-</programlisting>
-
-<indexterm><primary><literal>indexCharArray#</literal></primary></indexterm>
-<indexterm><primary><literal>indexIntArray#</literal></primary></indexterm>
-<indexterm><primary><literal>indexAddrArray#</literal></primary></indexterm>
-<indexterm><primary><literal>indexFloatArray#</literal></primary></indexterm>
-<indexterm><primary><literal>indexDoubleArray#</literal></primary></indexterm>
-<indexterm><primary><literal>indexCharOffAddr#</literal></primary></indexterm>
-<indexterm><primary><literal>indexIntOffAddr#</literal></primary></indexterm>
-<indexterm><primary><literal>indexFloatOffAddr#</literal></primary></indexterm>
-<indexterm><primary><literal>indexDoubleOffAddr#</literal></primary></indexterm>
-<indexterm><primary><literal>indexAddrOffAddr#</literal></primary></indexterm>
-</para>
-
-<para>
-The last of these, <function>indexAddrOffAddr#</function>, extracts an <literal>Addr#</literal> using an offset
-from another <literal>Addr#</literal>, thereby providing the ability to follow a chain of
-C pointers.
-</para>
-
-<para>
-Something a bit more interesting goes on when indexing arrays of boxed
-objects, because the result is simply the boxed object. So presumably
-it should be entered—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#</literal></primary></indexterm>
-</para>
-
-</sect2>
-
-<sect2>
-<title>The state type</title>
-
-<para>
-<indexterm><primary><literal>state, primitive type</literal></primary></indexterm>
-<indexterm><primary><literal>State#</literal></primary></indexterm>
-</para>
-
-<para>
-The primitive type <literal>State#</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#</literal> are represented in the same way.
-Indeed, they are all represented by nothing at all! The code
-generator “knows” to generate no code, and allocate no registers
-etc, for primitive states.
-</para>
-
-<para>
-
-<programlisting>
-type State# s
-</programlisting>
-
-</para>
-
-<para>
-The type <literal>GHC.RealWorld</literal> is truly opaque: there are no values defined
-of this type, and no operations over it. It is “primitive” 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>
-data RealWorld
-</programlisting>
-
-</para>
-
-</sect2>
-
-<sect2>
-<title>State of the world</title>
-
-<para>
-A single, primitive, value of type <literal>State# RealWorld</literal> is provided.
-</para>
-
-<para>
-
-<programlisting>
-realWorld# :: State# RealWorld
-</programlisting>
-
-<indexterm><primary>realWorld# state object</primary></indexterm>
-</para>
-
-<para>
-(Note: in the compiler, not a <literal>PrimOp</literal>; just a mucho magic
-<literal>Id</literal>. Exported from <literal>GHC</literal>, though).
-</para>
-
-</sect2>
-
-<sect2 id="sect-mutable">
-<title>Mutable arrays</title>
-
-<para>
-<indexterm><primary>mutable arrays</primary></indexterm>
-<indexterm><primary>arrays, mutable</primary></indexterm>
-Corresponding to <literal>Array#</literal> and <literal>ByteArray#</literal>, we have the types of
-mutable versions of each. In each case, the representation is a
-pointer to a suitable block of (mutable) heap-allocated storage.
-</para>
-
-<para>
-
-<programlisting>
-type MutableArray# s elt
-type MutableByteArray# s
-</programlisting>
-
-<indexterm><primary><literal>MutableArray#</literal></primary></indexterm>
-<indexterm><primary><literal>MutableByteArray#</literal></primary></indexterm>
-</para>
-
-<sect3>
-<title>Allocation</title>
-
-<para>
-<indexterm><primary>mutable arrays, allocation</primary></indexterm>
-<indexterm><primary>arrays, allocation</primary></indexterm>
-<indexterm><primary>allocation, of mutable arrays</primary></indexterm>
-</para>
-
-<para>
-Mutable arrays can be allocated. Only pointer-arrays are initialised;
-arrays of non-pointers are filled in by “user code” rather than by
-the array-allocation primitive. Reason: only the pointer case has to
-worry about GC striking with a partly-initialised array.
-</para>
-
-<para>
-
-<programlisting>
-newArray# :: Int# -> elt -> State# s -> (# State# s, MutableArray# s elt #)
-
-newCharArray# :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
-newIntArray# :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
-newAddrArray# :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
-newFloatArray# :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
-newDoubleArray# :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
-</programlisting>
-
-<indexterm><primary><literal>newArray#</literal></primary></indexterm>
-<indexterm><primary><literal>newCharArray#</literal></primary></indexterm>
-<indexterm><primary><literal>newIntArray#</literal></primary></indexterm>
-<indexterm><primary><literal>newAddrArray#</literal></primary></indexterm>
-<indexterm><primary><literal>newFloatArray#</literal></primary></indexterm>
-<indexterm><primary><literal>newDoubleArray#</literal></primary></indexterm>
-</para>
-
-<para>
-The size of a <literal>ByteArray#</literal> is given in bytes.
-</para>
-
-</sect3>
-
-<sect3>
-<title>Reading and writing</title>
-
-<para>
-<indexterm><primary>arrays, reading and writing</primary></indexterm>
-</para>
-
-<para>
-
-<programlisting>
-readArray# :: MutableArray# s elt -> Int# -> State# s -> (# State# s, elt #)
-readCharArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #)
-readIntArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
-readAddrArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Addr# #)
-readFloatArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Float# #)
-readDoubleArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Double# #)
-
-writeArray# :: MutableArray# s elt -> Int# -> elt -> State# s -> State# s
-writeCharArray# :: MutableByteArray# s -> Int# -> Char# -> State# s -> State# s
-writeIntArray# :: MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
-writeAddrArray# :: MutableByteArray# s -> Int# -> Addr# -> State# s -> State# s
-writeFloatArray# :: MutableByteArray# s -> Int# -> Float# -> State# s -> State# s
-writeDoubleArray# :: MutableByteArray# s -> Int# -> Double# -> State# s -> State# s
-</programlisting>
-
-<indexterm><primary><literal>readArray#</literal></primary></indexterm>
-<indexterm><primary><literal>readCharArray#</literal></primary></indexterm>
-<indexterm><primary><literal>readIntArray#</literal></primary></indexterm>
-<indexterm><primary><literal>readAddrArray#</literal></primary></indexterm>
-<indexterm><primary><literal>readFloatArray#</literal></primary></indexterm>
-<indexterm><primary><literal>readDoubleArray#</literal></primary></indexterm>
-<indexterm><primary><literal>writeArray#</literal></primary></indexterm>
-<indexterm><primary><literal>writeCharArray#</literal></primary></indexterm>
-<indexterm><primary><literal>writeIntArray#</literal></primary></indexterm>
-<indexterm><primary><literal>writeAddrArray#</literal></primary></indexterm>
-<indexterm><primary><literal>writeFloatArray#</literal></primary></indexterm>
-<indexterm><primary><literal>writeDoubleArray#</literal></primary></indexterm>
-</para>
-
-</sect3>
-
-<sect3>
-<title>Equality</title>
-
-<para>
-<indexterm><primary>arrays, testing for equality</primary></indexterm>
-</para>
-
-<para>
-One can take “equality” of mutable arrays. What is compared is the
-<emphasis>name</emphasis> or reference to the mutable array, not its contents.
-</para>
-
-<para>
-
-<programlisting>
-sameMutableArray# :: MutableArray# s elt -> MutableArray# s elt -> Bool
-sameMutableByteArray# :: MutableByteArray# s -> MutableByteArray# s -> Bool
-</programlisting>
-
-<indexterm><primary><literal>sameMutableArray#</literal></primary></indexterm>
-<indexterm><primary><literal>sameMutableByteArray#</literal></primary></indexterm>
-</para>
-
-</sect3>
-
-<sect3>
-<title>Freezing mutable arrays</title>
-
-<para>
-<indexterm><primary>arrays, freezing mutable</primary></indexterm>
-<indexterm><primary>freezing mutable arrays</primary></indexterm>
-<indexterm><primary>mutable arrays, freezing</primary></indexterm>
-</para>
-
-<para>
-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>
-unsafeFreezeArray# :: MutableArray# s elt -> State# s -> (# State# s, Array# s elt #)
-unsafeFreezeByteArray# :: MutableByteArray# s -> State# s -> (# State# s, ByteArray# #)
-</programlisting>
-
-<indexterm><primary><literal>unsafeFreezeArray#</literal></primary></indexterm>
-<indexterm><primary><literal>unsafeFreezeByteArray#</literal></primary></indexterm>
-</para>
-
-</sect3>
-
-</sect2>
-
-<sect2>
-<title>Synchronizing variables (M-vars)</title>
-
-<para>
-<indexterm><primary>synchronising variables (M-vars)</primary></indexterm>
-<indexterm><primary>M-Vars</primary></indexterm>
-</para>
-
-<para>
-Synchronising variables are the primitive type used to implement
-Concurrent Haskell's MVars (see the Concurrent Haskell paper for
-the operational behaviour of these operations).
-</para>
-
-<para>
-
-<programlisting>
-type MVar# s elt -- primitive
-
-newMVar# :: State# s -> (# State# s, MVar# s elt #)
-takeMVar# :: SynchVar# s elt -> State# s -> (# State# s, elt #)
-putMVar# :: SynchVar# s elt -> State# s -> State# s
-</programlisting>
-
-<indexterm><primary><literal>SynchVar#</literal></primary></indexterm>
-<indexterm><primary><literal>newSynchVar#</literal></primary></indexterm>
-<indexterm><primary><literal>takeMVar</literal></primary></indexterm>
-<indexterm><primary><literal>putMVar</literal></primary></indexterm>
-</para>
-
-</sect2>
-
-</sect1>
-
-<sect1 id="glasgow-ST-monad">
-<title>Primitive state-transformer monad
-</title>
-
-<para>
-<indexterm><primary>state transformers (Glasgow extensions)</primary></indexterm>
-<indexterm><primary>ST monad (Glasgow extension)</primary></indexterm>
-</para>
-
-<para>
-This monad underlies our implementation of arrays, mutable and
-immutable, and our implementation of I/O, including “C calls”.
-</para>
-
-<para>
-The <literal>ST</literal> library, which provides access to the
-<function>ST</function> monad, is described in <xref
-linkend="sec-ST">.
-</para>
-
-</sect1>
-
-<sect1 id="glasgow-prim-arrays">
-<title>Primitive arrays, mutable and otherwise
-</title>
-
-<para>
-<indexterm><primary>primitive arrays (Glasgow extension)</primary></indexterm>
-<indexterm><primary>arrays, primitive (Glasgow extension)</primary></indexterm>
-</para>
-
-<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# obj</literal>) and primitive arrays of bytes (type
-<literal>ByteArray#</literal>).
-</para>
-
-<para>
-Second, it distinguishes between…
-<variablelist>
-
-<varlistentry>
-<term>Immutable:</term>
-<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.
-</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>.
-</para>
-</listitem>
-</varlistentry>
-<varlistentry>
-<term>“Static” (in C land):</term>
-<listitem>
-<para>
-A C routine may pass an <literal>Addr#</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.
-</para>
-</listitem>
-</varlistentry>
-<varlistentry>
-<term>“Stable” 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 “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.
-</para>
-
-<para>
-Please see <xref LinkEnd="sec-stable-pointers"> for more details.
-</para>
-</listitem>
-</varlistentry>
-<varlistentry>
-<term>“Foreign objects”:</term>
-<listitem>
-<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.”
-</para>
-
-<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
-“primitive array” types and the operations on them.
-</para>
-
-</sect1>
-
-
-<sect1 id="pattern-guards">
-<title>Pattern guards</title>
-
-<para>
-<indexterm><primary>Pattern guards (Glasgow extension)</primary></indexterm>
-The discussion that follows is an abbreviated version of Simon Peyton Jones's original <ULink URL="http://research.microsoft.com/~simonpj/Haskell/guards.html">proposal</ULink>. (Note that the proposal was written before pattern guards were implemented, so refers to them as unimplemented.)
-</para>
-
-<para>
-Suppose we have an abstract data type of finite maps, with a
-lookup operation:
-
-<programlisting>
-lookup :: FiniteMap -> Int -> Maybe Int
-</programlisting>
-
-The lookup returns <function>Nothing</function> if the supplied key is not in the domain of the mapping, and <function>(Just v)</function> otherwise,
-where <VarName>v</VarName> is the value that the key maps to. Now consider the following definition:
-</para>
-
-<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>
-maybeToBool :: Maybe a -> Bool
-maybeToBool (Just x) = True
-maybeToBool Nothing = False
-
-expectJust :: Maybe a -> a
-expectJust (Just x) = x
-expectJust Nothing = error "Unexpected Nothing"
-</programlisting>
-
-<para>
-What is <function>clunky</function> doing? The guard <literal>ok1 &&
-ok2</literal> checks that both lookups succeed, using
-<function>maybeToBool</function> to convert the <function>Maybe</function>
-types to booleans. The (lazily evaluated) <function>expectJust</function>
-calls extract the values from the results of the lookups, and binds the
-returned values to <VarName>val1</VarName> and <VarName>val2</VarName>
-respectively. If either lookup fails, then clunky takes the
-<literal>otherwise</literal> case and returns the sum of its arguments.
-</para>
-
-<para>
-This is certainly legal Haskell, but it is a tremendously verbose and
-un-obvious way to achieve the desired effect. Arguably, a more direct way
-to write clunky would be to use case expressions:
-</para>
-
-<programlisting>
-clunky env var1 var1 = case lookup env var1 of
- Nothing -> fail
- Just val1 -> case lookup env var2 of
- Nothing -> fail
- Just val2 -> val1 + val2
-where
- fail = val1 + val2
-</programlisting>
-
-<para>
-This is a bit shorter, but hardly better. Of course, we can rewrite any set
-of pattern-matching, guarded equations as case expressions; that is
-precisely what the compiler does when compiling equations! The reason that
-Haskell provides guarded equations is because they allow us to write down
-the cases we want to consider, one at a time, independently of each other.
-This structure is hidden in the case version. Two of the right-hand sides
-are really the same (<function>fail</function>), and the whole expression
-tends to become more and more indented.
-</para>
-
-<para>
-Here is how I would write clunky:
-</para>
-
-<programlisting>
-clunky env var1 var1
- | Just val1 <- lookup env var1
- , Just val2 <- 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><-</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><-</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.