-<Sect2 id="unboxed-tuples">
-<Title>Unboxed Tuples
-</Title>
-
-<Para>
-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>
-
-<ProgramListing>
-(# e_1, ..., e_n #)
-</ProgramListing>
-
-</Para>
-
-<Para>
-where <Literal>e_1..e_n</Literal> are expressions of any
-type (primitive or non-primitive). The type of an unboxed tuple looks
-the same.
-</Para>
-
-<Para>
-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>
-There are some pretty stringent restrictions on the use of unboxed tuples:
-</Para>
-
-<Para>
-
-<ItemizedList>
-<ListItem>
-
-<Para>
- 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>
-<ListItem>
-
-<Para>
- 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 #) -> a + b }
-</ProgramListing>
-
-
-but the following are invalid:
-
-
-<ProgramListing>
-f x y = g (# x, y #)
-g (# x, y #) = x + y
-</ProgramListing>
-
-
-</Para>
-</ListItem>
-<ListItem>
-
-<Para>
- No variable can have an unboxed tuple type. This is illegal:
-
-
-<ProgramListing>
-f :: (# Int, Int #) -> (# Int, Int #)
-f x = x
-</ProgramListing>
-
-
-because <VarName>x</VarName> has an unboxed tuple type.
-
-</Para>
-</ListItem>
-
-</ItemizedList>
-
-</Para>
-
-<Para>
-Note: we may relax some of these restrictions in the future.
-</Para>
-
-<Para>
-The <Literal>IO</Literal> and <Literal>ST</Literal> monads use unboxed tuples to avoid unnecessary
-allocation during sequences of operations.
-</Para>
-
-</Sect2>
-
-<Sect2>
-<Title>Character and numeric types</Title>
-
-<Para>
-<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>
-
-<ProgramListing>
-type Char#
-type Int#
-type Word#
-type Addr#
-type Float#
-type Double#
-type Int64#
-type Word64#
-</ProgramListing>
-
-<IndexTerm><Primary><literal>Char#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>Int#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>Word#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>Addr#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>Float#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>Double#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>Int64#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>Word64#</literal></Primary></IndexTerm>
-</Para>
-
-<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>
-Literals for these types may be written as follows:
-</Para>
-
-<Para>
-
-<ProgramListing>
-1# an Int#
-1.2# a Float#
-1.34## a Double#
-'a'# a Char#; for weird characters, use '\o<octal>'#
-"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>comparisons, primitive</Primary></IndexTerm>
-<IndexTerm><Primary>operators, comparison</Primary></IndexTerm>
-</Para>
-
-<Para>
-
-<ProgramListing>
-{>,>=,==,/=,<,<=}# :: Int# -> Int# -> Bool
-
-{gt,ge,eq,ne,lt,le}Char# :: Char# -> Char# -> Bool
- -- ditto for Word# and Addr#
-</ProgramListing>
-
-<IndexTerm><Primary><literal>>#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>>=#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>==#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>/=#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal><#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal><=#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>gt{Char,Word,Addr}#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>ge{Char,Word,Addr}#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>eq{Char,Word,Addr}#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>ne{Char,Word,Addr}#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>lt{Char,Word,Addr}#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>le{Char,Word,Addr}#</literal></Primary></IndexTerm>
-</Para>
-
-</Sect2>
-
-<Sect2>
-<Title>Primitive-character operations</Title>
-
-<Para>
-<IndexTerm><Primary>characters, primitive operations</Primary></IndexTerm>
-<IndexTerm><Primary>operators, primitive character</Primary></IndexTerm>
-</Para>
-
-<Para>
-
-<ProgramListing>
-ord# :: Char# -> Int#
-chr# :: Int# -> Char#
-</ProgramListing>
-
-<IndexTerm><Primary><literal>ord#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>chr#</literal></Primary></IndexTerm>
-</Para>
-
-</Sect2>
-
-<Sect2>
-<Title>Primitive-<Literal>Int</Literal> operations</Title>
-
-<Para>
-<IndexTerm><Primary>integers, primitive operations</Primary></IndexTerm>
-<IndexTerm><Primary>operators, primitive integer</Primary></IndexTerm>
-</Para>
-
-<Para>
-
-<ProgramListing>
-{+,-,*,quotInt,remInt,gcdInt}# :: Int# -> Int# -> Int#
-negateInt# :: Int# -> Int#
-
-iShiftL#, iShiftRA#, iShiftRL# :: Int# -> Int# -> Int#
- -- shift left, right arithmetic, right logical
-
-addIntC#, subIntC#, mulIntC# :: Int# -> Int# -> (# Int#, Int# #)
- -- add, subtract, multiply with carry
-</ProgramListing>
-
-<IndexTerm><Primary><literal>+#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>-#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>*#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>quotInt#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>remInt#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>gcdInt#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>iShiftL#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>iShiftRA#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>iShiftRL#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>addIntC#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>subIntC#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>mulIntC#</literal></Primary></IndexTerm>
-<IndexTerm><Primary>shift operations, integer</Primary></IndexTerm>
-</Para>
-
-<Para>
-<Emphasis>Note:</Emphasis> No error/overflow checking!
-</Para>
-
-</Sect2>
-
-<Sect2>
-<Title>Primitive-<Literal>Double</Literal> and <Literal>Float</Literal> operations</Title>
-
-<Para>
-<IndexTerm><Primary>floating point numbers, primitive</Primary></IndexTerm>
-<IndexTerm><Primary>operators, primitive floating point</Primary></IndexTerm>
-</Para>
-
-<Para>
-
-<ProgramListing>
-{+,-,*,/}## :: Double# -> Double# -> Double#
-{<,<=,==,/=,>=,>}## :: Double# -> Double# -> Bool
-negateDouble# :: Double# -> Double#
-double2Int# :: Double# -> Int#
-int2Double# :: Int# -> Double#
-
-{plus,minux,times,divide}Float# :: Float# -> Float# -> Float#
-{gt,ge,eq,ne,lt,le}Float# :: Float# -> Float# -> Bool
-negateFloat# :: Float# -> Float#
-float2Int# :: Float# -> Int#
-int2Float# :: Int# -> Float#
-</ProgramListing>
-
-</Para>
-
-<Para>
-<IndexTerm><Primary><literal>+##</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>-##</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>*##</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>/##</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal><##</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal><=##</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>==##</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>=/##</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>>=##</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>>##</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>negateDouble#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>double2Int#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>int2Double#</literal></Primary></IndexTerm>
-</Para>
-
-<Para>
-<IndexTerm><Primary><literal>plusFloat#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>minusFloat#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>timesFloat#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>divideFloat#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>gtFloat#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>geFloat#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>eqFloat#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>neFloat#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>ltFloat#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>leFloat#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>negateFloat#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>float2Int#</literal></Primary></IndexTerm>
-<IndexTerm><Primary><literal>int2Float#</literal></Primary></IndexTerm>
-</Para>
-
-<Para>
-And a full complement of trigonometric functions:
-</Para>
-
-<Para>
-
-<ProgramListing>
-expDouble# :: Double# -> Double#
-logDouble# :: Double# -> Double#
-sqrtDouble# :: Double# -> Double#
-sinDouble# :: Double# -> Double#
-cosDouble# :: Double# -> Double#
-tanDouble# :: Double# -> Double#
-asinDouble# :: Double# -> Double#
-acosDouble# :: Double# -> Double#
-atanDouble# :: Double# -> Double#
-sinhDouble# :: Double# -> Double#
-coshDouble# :: Double# -> Double#
-tanhDouble# :: Double# -> Double#
-powerDouble# :: Double# -> Double# -> Double#
-</ProgramListing>
-
-<IndexTerm><Primary>trigonometric functions, primitive</Primary></IndexTerm>
-</Para>
-
-<Para>
-similarly for <Literal>Float#</Literal>.
-</Para>
-
-<Para>
-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 a
-GHC/Hugs extension library and is described in the separate <ULink
-URL="libs.html"
->GHC/Hugs Extension Libraries</ULink
-> document.
-</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="glasgow-stablePtrs"> 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="glasgow-foreignObjs"> 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="glasgow-ccalls">
-<Title>Calling C directly from Haskell
-</Title>
-
-<Para>
-<IndexTerm><Primary>C calls (Glasgow extension)</Primary></IndexTerm>
-<IndexTerm><Primary>_ccall_ (Glasgow extension)</Primary></IndexTerm>
-<IndexTerm><Primary>_casm_ (Glasgow extension)</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.
-</Para>
-
-<Sect2 id="ccall-intro">
-<Title><Function>_ccall_</Function> and <Function>_casm_</Function>: an introduction
-</Title>
-
-<Para>
-The simplest way to use a simple C function
-</Para>
-
-<Para>
-
-<ProgramListing>
-double fooC( FILE *in, char c, int i, double d, unsigned int u )
-</ProgramListing>
-
-</Para>
-
-<Para>
-is to provide a Haskell wrapper:
-</Para>
-
-<Para>
-
-<ProgramListing>
-fooH :: Char -> Int -> Double -> Word -> IO Double
-fooH c i d w = _ccall_ fooC (“stdin”::Addr) c i d w
-</ProgramListing>
-
-</Para>
-
-<Para>
-The function <Function>fooH</Function> unbox all of its arguments, call the C
-function <Function>fooC</Function> and box the corresponding arguments.
-</Para>
-
-<Para>
-One of the annoyances about <Function>_ccall_</Function>s is when the C types don't quite
-match the Haskell compiler's ideas. For this, the <Function>_casm_</Function> variant
-may be just the ticket (NB: <Emphasis>no chance</Emphasis> of such code going
-through a native-code generator):
-</Para>
-
-<Para>
-
-<ProgramListing>
-import Addr
-import CString
-
-oldGetEnv name
- = _casm_ “%r = getenv((char *) %0);” name >>= \ litstring ->
- return (
- if (litstring == nullAddr) then
- Left ("Fail:oldGetEnv:"++name)
- else
- Right (unpackCString litstring)
- )
-</ProgramListing>
-
-</Para>
-
-<Para>
-The first literal-literal argument to a <Function>_casm_</Function> is like a <Function>printf</Function>
-format: <Literal>%r</Literal> is replaced with the “result,” <Literal>%0</Literal>–<Literal>%n-1</Literal> are
-replaced with the 1st–nth arguments. As you can see above, it is an
-easy way to do simple C casting. Everything said about <Function>_ccall_</Function> goes
-for <Function>_casm_</Function> as well.
-</Para>
-
-<Para>
-The use of <Function>_casm_</Function> in your code does pose a problem to the compiler
-when it comes to generating an interface file for a freshly compiled
-module. Included in an interface file is the unfolding (if any) of a
-declaration. However, if a declaration's unfolding happens to contain
-a <Function>_casm_</Function>, its unfolding will <Emphasis>not</Emphasis> be emitted into the interface
-file even if it qualifies by all the other criteria. The reason why
-the compiler prevents this from happening is that unfolding <Function>_casm_</Function>s
-into an interface file unduly constrains how code that import your
-module have to be compiled. If an imported declaration is unfolded and
-it contains a <Function>_casm_</Function>, you now have to be using a compiler backend
-capable of dealing with it (i.e., the C compiler backend). If you are
-using the C compiler backend, the unfolded <Function>_casm_</Function> may still cause you
-problems since the C code snippet it contains may mention CPP symbols
-that were in scope when compiling the original module are not when
-compiling the importing module.
-</Para>
-
-<Para>
-If you're willing to put up with the drawbacks of doing cross-module
-inlining of C code (GHC - A Better C Compiler :-), the option
-<Option>-funfold-casms-in-hi-file</Option> will turn off the default behaviour.
-<IndexTerm><Primary>-funfold-casms-in-hi-file option</Primary></IndexTerm>
-</Para>
-
-</Sect2>
-
-<Sect2 id="glasgow-literal-literals">
-<Title>Literal-literals</Title>
-
-<Para>
-<IndexTerm><Primary>Literal-literals</Primary></IndexTerm>
-The literal-literal argument to <Function>_casm_</Function> can be made use of separately
-from the <Function>_casm_</Function> construct itself. Indeed, we've already used it:
-</Para>
-
-<Para>
-
-<ProgramListing>
-fooH :: Char -> Int -> Double -> Word -> IO Double
-fooH c i d w = _ccall_ fooC (“stdin”::Addr) c i d w
-</ProgramListing>
-
-</Para>
-
-<Para>
-The first argument that's passed to <Function>fooC</Function> is given as a literal-literal,
-that is, a literal chunk of C code that will be inserted into the generated
-<Filename>.hc</Filename> code at the right place.
-</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.
-</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.
-</Para>
-
-</Sect2>
-
-<Sect2 id="glasgow-foreign-headers">
-<Title>Using function headers
-</Title>
-
-<Para>
-<IndexTerm><Primary>C calls, function headers</Primary></IndexTerm>
-</Para>
-
-<Para>
-When generating C (using the <Option>-fvia-C</Option> directive), one can assist the
-C compiler in detecting type errors by using the <Command>-#include</Command> directive
-to provide <Filename>.h</Filename> files containing function headers.
-</Para>
-
-<Para>
-For example,
-</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 <Command>gcc</Command> on your architecture by consulting
-<Filename>ghc/includes/StgTypes.h</Filename>. The following table summarises the
-relationship between Haskell types and C types.
-</Para>
-
-<Para>
-
-<InformalTable>
-<TGroup Cols="2">
-<ColSpec Align="Left" Colsep="0">
-<ColSpec Align="Left" Colsep="0">
-<TBody>
-<Row>
-<Entry><Emphasis>C type name</Emphasis> </Entry>
-<Entry> <Emphasis>Haskell Type</Emphasis> </Entry>
-</Row>
-
-<Row>
-<Entry>
-<Literal>StgChar</Literal> </Entry>
-<Entry> <Literal>Char#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgInt</Literal> </Entry>
-<Entry> <Literal>Int#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgWord</Literal> </Entry>
-<Entry> <Literal>Word#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgAddr</Literal> </Entry>
-<Entry> <Literal>Addr#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgFloat</Literal> </Entry>
-<Entry> <Literal>Float#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgDouble</Literal> </Entry>
-<Entry> <Literal>Double#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgArray</Literal> </Entry>
-<Entry> <Literal>Array#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgByteArray</Literal> </Entry>
-<Entry> <Literal>ByteArray#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgArray</Literal> </Entry>
-<Entry> <Literal>MutableArray#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgByteArray</Literal> </Entry>
-<Entry> <Literal>MutableByteArray#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgStablePtr</Literal> </Entry>
-<Entry> <Literal>StablePtr#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgForeignObj</Literal> </Entry>
-<Entry> <Literal>ForeignObj#</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.
-</Para>
-
-</Sect2>
-
-<Sect2 id="glasgow-stablePtrs">
-<Title>Subverting automatic unboxing with “stable pointers”
-</Title>
-
-<Para>
-<IndexTerm><Primary>stable pointers (Glasgow extension)</Primary></IndexTerm>
-</Para>
-
-<Para>
-The arguments of a <Function>_ccall_</Function> automatically unboxed before the
-call. There are two reasons why this is usually the Right Thing to
-do:
-</Para>
-
-<Para>
-
-<ItemizedList>
-<ListItem>
-
-<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.
-
-</Para>
-</ListItem>
-<ListItem>
-
-<Para>
- Boxed values are stored on the Haskell heap and may be moved
-within the heap if a garbage collection occurs—that is, pointers
-to boxed objects are not <Emphasis>stable</Emphasis>.
-</Para>
-</ListItem>
-
-</ItemizedList>
-
-</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 <Function>storeC</Function> and
-<Function>fetchC</Function> might write:
-</Para>
-
-<Para>
-
-<ProgramListing>
-storeH :: Int -> IO ()
-storeH x = makeStablePtr x >>= \ stable_x ->
- _ccall_ storeC stable_x
-
-fetchH :: IO Int
-fetchH x = _ccall_ fetchC >>= \ stable_x ->
- deRefStablePtr stable_x >>= \ x ->
- freeStablePtr stable_x >>
- return x
-</ProgramListing>
-
-</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.
-</Para>
-
-<Para>
-
-<ProgramListing>
-void freeStablePointer( StgStablePtr stablePtrToToss )
-freeStablePtr :: StablePtr a -> IO ()
-</ProgramListing>
-
-</Para>
-
-<Para>
-As with the use of <Function>free</Function> in C programs, GREAT CARE SHOULD BE
-EXERCISED to ensure these functions are called at the right time: too
-early and you get dangling references (and, if you're lucky, an error
-message from the runtime system); too late and you get space leaks.
-</Para>
-
-<Para>
-And to force evaluation of the argument within <Function>fooC</Function>, one would
-call one of the following C functions (according to type of argument).
-</Para>
-
-<Para>
-
-<ProgramListing>
-void performIO ( StgStablePtr stableIndex /* StablePtr s (IO ()) */ );
-StgInt enterInt ( StgStablePtr stableIndex /* StablePtr s Int */ );
-StgFloat enterFloat ( StgStablePtr stableIndex /* StablePtr s Float */ );
-</ProgramListing>
-
-</Para>
-
-<Para>
-<IndexTerm><Primary>performIO</Primary></IndexTerm>
-<IndexTerm><Primary>enterInt</Primary></IndexTerm>
-<IndexTerm><Primary>enterFloat</Primary></IndexTerm>
-</Para>
-
-<Para>
-Nota Bene: <Function>_ccall_GC_</Function><IndexTerm><Primary>_ccall_GC_</Primary></IndexTerm> must be used if any of
-these functions are used.
-</Para>
-
-</Sect2>
-
-<Sect2 id="glasgow-foreignObjs">
-<Title>Foreign objects: pointing outside the Haskell heap
-</Title>
-
-<Para>
-<IndexTerm><Primary>foreign objects (Glasgow extension)</Primary></IndexTerm>
-</Para>
-
-<Para>
-There are two types that GHC programs can use to reference
-(heap-allocated) objects outside the Haskell world: <Literal>Addr</Literal> and
-<Literal>ForeignObj</Literal>.
-</Para>
-
-<Para>
-If you use <Literal>Addr</Literal>, it is up to you to the programmer to arrange
-allocation and deallocation of the objects.
-</Para>
-
-<Para>
-If you use <Literal>ForeignObj</Literal>, GHC's garbage collector will call upon the
-user-supplied <Emphasis>finaliser</Emphasis> function to free the object when the
-Haskell world no longer can access the object. (An object is
-associated with a finaliser function when the abstract
-Haskell type <Literal>ForeignObj</Literal> is created). The finaliser function is
-expressed in C, and is passed as argument the object:
-</Para>
-
-<Para>
-
-<ProgramListing>
-void foreignFinaliser ( StgForeignObj fo )
-</ProgramListing>
-
-</Para>
-
-<Para>
-when the Haskell world can no longer access the object. Since
-<Literal>ForeignObj</Literal>s only get released when a garbage collection occurs, we
-provide ways of triggering a garbage collection from within C and from
-within Haskell.
-</Para>
-
-<Para>
-
-<ProgramListing>
-void GarbageCollect()
-performGC :: IO ()
-</ProgramListing>
-
-</Para>
-
-<Para>
-More information on the programmers' interface to <Literal>ForeignObj</Literal> can be
-found in the library documentation.
-</Para>
-
-</Sect2>
-
-<Sect2 id="glasgow-avoiding-monads">
-<Title>Avoiding monads
-</Title>
-
-<Para>
-<IndexTerm><Primary>C calls to `pure C'</Primary></IndexTerm>
-<IndexTerm><Primary>unsafePerformIO</Primary></IndexTerm>
-</Para>
-
-<Para>
-The <Function>_ccall_</Function> construct is part of the <Literal>IO</Literal> monad because 9 out of 10
-uses will be to call imperative functions with side effects such as
-<Function>printf</Function>. Use of the monad ensures that these operations happen in a
-predictable order in spite of laziness and compiler optimisations.
-</Para>
-
-<Para>
-To avoid having to be in the monad to call a C function, it is
-possible to use <Function>unsafePerformIO</Function>, which is available from the
-<Literal>IOExts</Literal> module. There are three situations where one might like to
-call a C function from outside the IO world:
-</Para>
-
-<Para>
-
-<ItemizedList>
-<ListItem>
-
-<Para>
-Calling a function with no side-effects:
-
-<ProgramListing>
-atan2d :: Double -> Double -> Double
-atan2d y x = unsafePerformIO (_ccall_ atan2d y x)
-
-sincosd :: Double -> (Double, Double)
-sincosd x = unsafePerformIO $ do
- da <- newDoubleArray (0, 1)
- _casm_ “sincosd( %0, &((double *)%1[0]), &((double *)%1[1]) );” x da
- s <- readDoubleArray da 0
- c <- readDoubleArray da 1
- return (s, c)
-</ProgramListing>
-
-
-</Para>
-</ListItem>
-<ListItem>
-
-<Para>
- Calling a set of functions which have side-effects but which can
-be used in a purely functional manner.
-
-For example, an imperative implementation of a purely functional
-lookup-table might be accessed using the following functions.
-
-
-<ProgramListing>
-empty :: EFS x
-update :: EFS x -> Int -> x -> EFS x
-lookup :: EFS a -> Int -> a
-
-empty = unsafePerformIO (_ccall_ emptyEFS)
-
-update a i x = unsafePerformIO $
- makeStablePtr x >>= \ stable_x ->
- _ccall_ updateEFS a i stable_x
-
-lookup a i = unsafePerformIO $
- _ccall_ lookupEFS a i >>= \ stable_x ->
- deRefStablePtr stable_x
-</ProgramListing>
-
-
-You will almost always want to use <Literal>ForeignObj</Literal>s with this.
-
-</Para>
-</ListItem>
-<ListItem>
-
-<Para>
- Calling a side-effecting function even though the results will
-be unpredictable. For example the <Function>trace</Function> function is defined by:
-
-
-<ProgramListing>
-trace :: String -> a -> a
-trace string expr
- = unsafePerformIO (
- ((_ccall_ PreTraceHook sTDERR{-msg-}):: IO ()) >>
- fputs sTDERR string >>
- ((_ccall_ PostTraceHook sTDERR{-msg-}):: IO ()) >>
- return expr )
- where
- sTDERR = (“stderr” :: Addr)
-</ProgramListing>
-
-
-(This kind of use is not highly recommended—it is only really
-useful in debugging code.)
-</Para>
-</ListItem>
-
-</ItemizedList>
-
-</Para>
-
-</Sect2>
-
-<Sect2 id="ccall-gotchas">
-<Title>C-calling “gotchas” checklist
-</Title>
-
-<Para>
-<IndexTerm><Primary>C call dangers</Primary></IndexTerm>
-<IndexTerm><Primary>CCallable</Primary></IndexTerm>
-<IndexTerm><Primary>CReturnable</Primary></IndexTerm>
-</Para>
-
-<Para>
-And some advice, too.
-</Para>
-
-<Para>
-
-<ItemizedList>
-<ListItem>
-
-<Para>
- For modules that use <Function>_ccall_</Function>s, etc., compile with
-<Option>-fvia-C</Option>.<IndexTerm><Primary>-fvia-C option</Primary></IndexTerm> You don't have to, but you should.
-
-Also, use the <Option>-#include "prototypes.h"</Option> flag (hack) to inform the C
-compiler of the fully-prototyped types of all the C functions you
-call. (<XRef LinkEnd="glasgow-foreign-headers"> says more about this…)
-
-This scheme is the <Emphasis>only</Emphasis> way that you will get <Emphasis>any</Emphasis>
-typechecking of your <Function>_ccall_</Function>s. (It shouldn't be that way, but…).
-GHC will pass the flag <Option>-Wimplicit</Option> to <Command>gcc</Command> so that you'll get warnings
-if any <Function>_ccall_</Function>ed functions have no prototypes.
-
-</Para>
-</ListItem>
-<ListItem>
-
-<Para>
-Try to avoid <Function>_ccall_</Function>s to C 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.
-
-If you do use <Literal>floats</Literal>, check and re-check that the right thing is
-happening. Perhaps compile with <Option>-keep-hc-file-too</Option> and look at
-the intermediate C (<Function>.hc</Function>).
-
-</Para>
-</ListItem>
-<ListItem>
-
-<Para>
- The compiler uses two non-standard type-classes when
-type-checking the arguments and results of <Function>_ccall_</Function>: the arguments
-(respectively result) of <Function>_ccall_</Function> must be instances of the class
-<Literal>CCallable</Literal> (respectively <Literal>CReturnable</Literal>). Both classes may be
-imported from the module <Literal>CCall</Literal>, but this should only be
-necessary if you want to define a new instance. (Neither class
-defines any methods—their only function is to keep the
-type-checker happy.)
-
-The type checker must be able to figure out just which of the
-C-callable/returnable types is being used. If it can't, you have to
-add type signatures. For example,
-
-
-<ProgramListing>
-f x = _ccall_ foo x
-</ProgramListing>
-
-
-is not good enough, because the compiler can't work out what type <VarName>x</VarName>
-is, nor what type the <Function>_ccall_</Function> returns. You have to write, say:
-
-
-<ProgramListing>
-f :: Int -> 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…</Emphasis> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Char</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>unsigned char</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Int</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>long int</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Word</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>unsigned long int</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Addr</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>void *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Float</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>float</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Double</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>double</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>()</Literal> </Entry>
-<Entry> No </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>void</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>[Char]</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>char *</Literal> (null-terminated) </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Array</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>ByteArray</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>MutableArray</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>MutableByteArray</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>State</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> nothing!</Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StablePtr</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>ForeignObjs</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> see later </Entry>
-</Row>
-
-</TBody>
-
-</TGroup>
-</InformalTable>
-
-Actually, the <Literal>Word</Literal> type is defined as being the same size as a
-pointer on the target architecture, which is <Emphasis>probably</Emphasis>
-<Literal>unsigned long int</Literal>.
-
-The brave and careful programmer can add their own instances of these
-classes for the following types:
-
-
-<ItemizedList>
-<ListItem>
-
-<Para>
-A <Emphasis>boxed-primitive</Emphasis> type may be made an instance of both
-<Literal>CCallable</Literal> and <Literal>CReturnable</Literal>.
-
-A boxed primitive type is any data type with a
-single unary constructor with a single primitive argument. For
-example, the following are all boxed primitive types:
-
-
-<ProgramListing>
-Int
-Double
-data XDisplay = XDisplay Addr#
-data EFS a = EFS# ForeignObj#
-</ProgramListing>
-
-
-
-<ProgramListing>
-instance CCallable (EFS a)
-instance CReturnable (EFS a)
-</ProgramListing>
-
-
-</Para>
-</ListItem>
-<ListItem>
-
-<Para>
- Any datatype with a single nullary constructor may be made an
-instance of <Literal>CReturnable</Literal>. For example:
-
-
-<ProgramListing>
-data MyVoid = MyVoid
-instance CReturnable MyVoid
-</ProgramListing>
-
-
-</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.
-
-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…)
-</Para>
-</ListItem>
-
-</ItemizedList>
-
-
-</Para>
-</ListItem>
-<ListItem>
-
-<Para>
- The code-generator will complain if you attempt to use <Literal>%r</Literal> in
-a <Literal>_casm_</Literal> whose result type is <Literal>IO ()</Literal>; or if you don't use <Literal>%r</Literal>
-<Emphasis>precisely</Emphasis> once for any other result type. These messages are
-supposed to be helpful and catch bugs—please tell us if they wreck
-your life.