%
-% $Id: libraries.vsgml,v 1.2 1998/08/25 18:07:57 sof Exp $
+% $Id: libraries.vsgml,v 1.4 1999/02/02 14:14:12 sof Exp $
%
% GHC Prelude and Libraries.
%
<tag>@fromInt@ method in class @Num@:</tag> It's there. Converts from
an @Int@ to the type.
-<tag>@toInt@ method in class @Integral@:</tag> Converts from type type
-to an @Int@.
+<tag>@toInt@ method in class @Integral@:</tag> Converts from Integral
+type to an @Int@.
</descrip>
GHC also internally uses a number of modules that begin with the
-string @Prel@: for this reason, we don't recommend that you use any
-module names beginning with @Prel@ in your own programs. The @Prel@
-modules are always available: in fact, you can get access to several
-extensions this way (for some you might need to give the
-@-fglasgow-exts@<nidx>-fglasgow-exts option</nidx> flag).
+string @Prel@<nidx>Prel module prefix</nidx>: for this reason, we
+don't recommend that you use any module names beginning with @Prel@ in
+your own programs. The @Prel@ modules are always available: in fact,
+you can get access to several extensions this way (for some you might
+need to give the @-fglasgow-exts@<nidx>-fglasgow-exts option</nidx>
+flag).
+
+
+<sect1>GHC/Hugs Extension Libraries
+<p>
+
+The extension libraries provided by both GHC and Hugs are described in
+the
+<htmlurl name="GHC/Hugs Extension Library Document" url="http://www.dcs.gla.ac.uk/fp/software/ghc/hg-libs/hg-libs.html">
+
+<sect1>GHC-only Extension Libraries
+<p>
+<nidx>libraries, ghc-only</nidx>
+<nidx>extension libraries, ghc-only</nidx>
+
+If you rely on the implicit @import Prelude@ that GHC normally does
+for you, and if you don't use any weird flags (notably
+@-fglasgow-exts@), and if you don't import the Glasgow extensions
+interface, @GlaExts@, then GHC should work <em>exactly</em> as the
+Haskell report says (modulo a few minor issues, see Section <ref
+id="vs-Haskell-defn" name="Language Non-compliance">).
+
+If you turn on @-fglasgow-exts@, a new world opesn up to you and the compiler
+will recognise and parse unboxed values properly, and provide access to the
+various interfaces libraries described here (and piles of other goodies.)
+
+&mutablearray;
+&bytearray;
+
+<sect2>The @CCall@ module
+<p>
+
+The @CCall@ module defines the classes @CCallable@ and @CReturnable@,
+along with instances for the primitive types (@Int@, @Int#@, @Float@,
+@Float#@ etc.) GHC knows to import this module if you use @_ccall_@,
+but if you need to define your own instances of these classes, you
+will need to import @CCall@ explicitly.
+
+More information on how to use @_ccall_@ can be found in Section
+<ref name="Calling~C directly from Haskell" id="glasgow-ccalls">.
+
+<sect2>The @GlaExts@ interface
+<p>
+<nidx>GlaExts interface (GHC extensions)</nidx>
+
+The @GlaExts@ interface provides access to extensions that only GHC
+implements. These currently are: unboxed types, including the
+representations of the primitive types (Int, Float, etc.), and the
+GHC primitive operations (@+#@, @==#@, etc.).
+
+This module used to provide access to all the Glasgow extensions, but
+these have since been moved into separate libraries for compatibility
+with Hugs (version 2.09: in fact, you can still get at this stuff via
+@GlaExts@ for compatibility, but this facility will likely be removed
+in the future).
+
+<tscreen><verb>
+-- the representation of some basic types:
+data Char = C# Char#
+data Int = I# Int#
+data Addr = A# Addr#
+data Word = W# Word#
+data Float = F# Float#
+data Double = D# Double#
+data Integer = J# Int# Int# ByteArray#
+
+module GHC -- all primops and primitive types.
+</verb></tscreen>
<sect1>The module @PrelGHC@: really primitive stuff
<label id="ghc-libs-ghc">
<p>
+<nidx>PrelGHC module</nidx>
-This section defines all the types which are primitive in Glasgow
+This module defines all the types which are primitive in Glasgow
Haskell, and the operations provided for them.
A primitive type is one which cannot be defined in Haskell, and which
is therefore built into the language and compiler. Primitive types
-are always unboxed; that is, a value of primitive type cannot be
-bottom.
+are always unlifted; that is, a value of primitive type cannot be
+bottom. We use the convention that primitive types, values, and
+operations have a @#@ suffix.
Primitive values are often represented by a simple bit-pattern, such
as @Int#@, @Float#@, @Double#@. But this is not necessarily the case:
a primitive value might be represented by a pointer to a
heap-allocated object. Examples include @Array#@, the type of
-primitive arrays. You might think this odd: doesn't being
-heap-allocated mean that it has a box? No, it does not. 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...nothing can be at the other
-end of the pointer than the primitive value.
-
-This section also describes a few non-primitive types, which are needed
-to express the result types of some primitive operations.
+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...nothing can be at the other end of the pointer than the
+primitive value.
+
+<sect2>Unboxed Tuples
+<label id="unboxed-tuples">
+<p>
+
+Unboxed tuples aren't really exported by @PrelGHC@, they're available
+by default with @-fglasgow-exts@. An unboxed tuple looks like this:
+
+<tscreen><verb>
+(# e_1, ..., e_n #)
+</verb></tscreen>
+
+where @e_1..e_n@ are expressions of any type (primitive or
+non-primitive). The type of an unboxed tuple looks the same.
+
+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.
+
+There are some pretty stringent restrictions on the use of unboxed tuples:
+
+<itemize>
+
+<item> 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.
+
+<item> Unboxed tuples may only be constructed as the direct result of
+a function, and may only be deconstructed with a @case@ expression.
+eg. the following are valid:
+
+<tscreen><verb>
+f x y = (# x+1, y-1 #)
+g x = case f x x of { (# a, b #) -> a + b }
+</verb></tscreen>
+
+but the following are invalid:
+
+<tscreen><verb>
+f x y = g (# x, y #)
+g (# x, y #) = x + y
+</verb></tscreen>
+
+<item> No variable can have an unboxed tuple type. This is illegal:
+
+<tscreen><verb>
+f :: (# Int, Int #) -> (# Int, Int #)
+f x = x
+</verb></tscreen>
+
+because @x@ has an unboxed tuple type.
+
+</itemize>
+
+Note: we may relax some of these restrictions in the future.
+
+The @IO@ and @ST@ monads use unboxed tuples to avoid unnecessary
+allocation during sequences of operations.
<sect2>Character and numeric types
<p>
<ncdx>Double#</ncdx>
If you really want to know their exact equivalents in C, see
-@ghc/includes/StgTypes.lh@ in the GHC source tree.
+@ghc/includes/StgTypes.h@ in the GHC source tree.
Literals for these types may be written as follows:
<sect2> Primitive-character operations
<p>
-<nidx>characters, primitive</nidx>
+<nidx>characters, primitive operations</nidx>
<nidx>operators, primitive character</nidx>
<tscreen><verb>
<sect2> Primitive-@Int@ operations
<p>
-<nidx>integers, primitive</nidx>
+<nidx>integers, primitive operations</nidx>
<nidx>operators, primitive integer</nidx>
<tscreen><verb>
(And the same for @Float#@s.)
<sect2>Operations on/for @Integers@ (interface to GMP)
-<label id="horrid-Integer-pairing-types">
+<label id="integer-operations">
<p>
<nidx>arbitrary precision integers</nidx>
<nidx>Integer, operations on</nidx>
We implement @Integers@ (arbitrary-precision integers) using the GNU
-multiple-precision (GMP) package (version 1.3.2).
-
-<bf>Note:</bf> some of this might change when we upgrade to using
-GMP~2.x.
+multiple-precision (GMP) package (version 2.0.2).
The data type for @Integer@ must mirror that for @MP_INT@ in @gmp.h@
(see @gmp.info@ in @ghc/includes/runtime/gmp@). It comes out as:
So, @Integer@ is really just a ``pairing'' type for a particular
collection of primitive types.
-The operations in the GMP return other combinations of
-GMP-plus-something, so we need ``pairing'' types for those, too:
-
-<tscreen><verb>
-data Return2GMPs = Return2GMPs Int# Int# ByteArray# Int# Int# ByteArray#
-data ReturnIntAndGMP = ReturnIntAndGMP Int# Int# Int# ByteArray#
-
--- ????? something to return a string of bytes (in the heap?)
-</verb></tscreen>
-<ncdx>Return2GMPs</ncdx>
-<ncdx>ReturnIntAndGMP</ncdx>
-
The primitive ops to support @Integers@ use the ``pieces'' of the
representation, and are as follows:
not# :: Word# -> Word#
-shiftL#, shiftRL# :: Word# -> Int# -> Word#
- -- shift left, right logical
+shiftL#, shiftRA#, shiftRL# :: Word# -> Int# -> Word#
+ -- shift left, right arithmetic, right logical
int2Word# :: Int# -> Word# -- just a cast, really
word2Int# :: Word# -> Int#
<ncdx>quotWord#</ncdx>
<ncdx>remWord#</ncdx>
<ncdx>shiftL#</ncdx>
+<ncdx>shiftRA#</ncdx>
<ncdx>shiftRL#</ncdx>
<ncdx>int2Word#</ncdx>
<ncdx>word2Int#</ncdx>
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 lifted value, but I don't like it!
+return a single element unboxed tuple (see Section <ref name="Unboxed
+Tuples" id="unboxed-tuples">).
<tscreen><verb>
-indexArray# :: Array# elt -> Int# -> PrelBase.Lift elt -- Yuk!
+indexArray# :: Array# elt -> Int# -> (# elt #)
</verb></tscreen>
<ncdx>indexArray#</ncdx>
The type @GHC.RealWorld@ 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 <em>not unboxed!</em> Its only role in life is to be
+sense - but it is <em>not unlifted!</em> Its only role in life is to be
the type which distinguishes the @IO@ state transformer.
<tscreen><verb>
A single, primitive, value of type @State# RealWorld@ is provided.
<tscreen><verb>
-realWorld# :: State# GHC.RealWorld
+realWorld# :: State# RealWorld
</verb></tscreen>
<nidx>realWorld# state object</nidx>
(Note: in the compiler, not a @PrimOp@; just a mucho magic
@Id@. Exported from @GHC@, though).
-<sect2>State pairing types
-<p>
-<label id="horrid-pairing-types">
-
-This subsection defines some types which, while they aren't quite
-primitive because we can define them in Haskell, are very nearly so.
-They define constructors which pair a primitive state with a value of
-each primitive type. They are required to express the result type of
-the primitive operations in the state monad.
-<tscreen><verb>
-data StateAndPtr# s elt = StateAndPtr# (State# s) elt
-
-data StateAndChar# s = StateAndChar# (State# s) Char#
-data StateAndInt# s = StateAndInt# (State# s) Int#
-data StateAndWord# s = StateAndWord# (State# s) Word#
-data StateAndFloat# s = StateAndFloat# (State# s) Float#
-data StateAndDouble# s = StateAndDouble# (State# s) Double#
-data StateAndAddr# s = StateAndAddr# (State# s) Addr#
-
-data StateAndStablePtr# s a = StateAndStablePtr# (State# s) (StablePtr# a)
-data StateAndForeignObj# s = StateAndForeignObj# (State# s) ForeignObj#
-data StateAndSynchVar# s a = StateAndSynchVar# (State# s) (SynchVar# a)
-
-data StateAndArray# s elt = StateAndArray# (State# s) (Array# elt)
-data StateAndMutableArray# s elt = StateAndMutableArray# (State# s) (MutableArray# s elt)
-data StateAndByteArray# s = StateAndByteArray# (State# s) ByteArray#
-data StateAndMutableByteArray# s = StateAndMutableByteArray# (State# s) (MutableByteArray# s)
-</verb></tscreen>
-
-Hideous.
-
<sect2>Mutable arrays
<p>
<label id="sect:mutable">
worry about GC striking with a partly-initialised array.
<tscreen><verb>
-newArray# :: Int# -> elt -> State# s -> StateAndMutableArray# s elt
+newArray# :: Int# -> elt -> State# s -> (# State# s, MutableArray# s elt #)
-newCharArray# :: Int# -> State# s -> StateAndMutableByteArray# s
-newIntArray# :: Int# -> State# s -> StateAndMutableByteArray# s
-newAddrArray# :: Int# -> State# s -> StateAndMutableByteArray# s
-newFloatArray# :: Int# -> State# s -> StateAndMutableByteArray# s
-newDoubleArray# :: Int# -> State# s -> StateAndMutableByteArray# s
+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 #)
</verb></tscreen>
<ncdx>newArray#</ncdx>
<ncdx>newCharArray#</ncdx>
<nidx>arrays, reading and writing</nidx>
<tscreen><verb>
-readArray# :: MutableArray# s elt -> Int# -> State# s -> StateAndPtr# s elt
-readCharArray# :: MutableByteArray# s -> Int# -> State# s -> StateAndChar# s
-readIntArray# :: MutableByteArray# s -> Int# -> State# s -> StateAndInt# s
-readAddrArray# :: MutableByteArray# s -> Int# -> State# s -> StateAndAddr# s
-readFloatArray# :: MutableByteArray# s -> Int# -> State# s -> StateAndFloat# s
-readDoubleArray# :: MutableByteArray# s -> Int# -> State# s -> StateAndDouble# s
+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
by copying the array and then using @unsafeFreeze@.)
<tscreen><verb>
-unsafeFreezeArray# :: MutableArray# s elt -> State# s -> StateAndArray# s elt
-unsafeFreezeByteArray# :: MutableByteArray# s -> State# s -> StateAndByteArray# s
+unsafeFreezeArray# :: MutableArray# s elt -> State# s -> (# State# s, Array# s elt #)
+unsafeFreezeByteArray# :: MutableByteArray# s -> State# s -> (# State# s, ByteArray# #)
</verb></tscreen>
<ncdx>unsafeFreezeArray#</ncdx>
<ncdx>unsafeFreezeByteArray#</ncdx>
copies.
<tscreen><verb>
-makeStablePointer# :: a -> State# RealWorld -> StateAndStablePtr# RealWorld a
+makeStablePointer# :: a -> State# RealWorld -> (# State# RealWord, StablePtr# a #)
freeStablePointer# :: StablePtr# a -> State# RealWorld -> State# RealWorld
-deRefStablePointer# :: StablePtr# a -> State# RealWorld -> StateAndPtr RealWorld a
+deRefStablePointer# :: StablePtr# a -> State# RealWorld -> (# State# RealWorld, a #)
</verb></tscreen>
<ncdx>makeStablePointer#</ncdx>
<ncdx>freeStablePointer#</ncdx>
makeForeignObj#
:: Addr# -- foreign reference
-> Addr# -- pointer to finalisation routine
- -> StateAndForeignObj# RealWorld ForeignObj#
+ -> (# State# RealWorld, ForeignObj# )
writeForeignObj
:: ForeignObj# -- foreign object
-> Addr# -- datum
the operational behaviour of these operations).
<tscreen><verb>
-type SynchVar# s elt -- primitive
+type MVar# s elt -- primitive
-newSynchVar#:: State# s -> StateAndSynchVar# s elt
-takeMVar# :: SynchVar# s elt -> State# s -> StateAndPtr# s elt
+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
</verb></tscreen>
<ncdx>SynchVar#</ncdx>
<ncdx>newSynchVar#</ncdx>
<ncdx>takeMVar</ncdx>
<ncdx>putMVar</ncdx>
-
-<sect2>@spark#@ primitive operation (for parallel execution)
-<p>
-<nidx>spark primitive operation</nidx>
-
-<em>ToDo: say something</em> It's used in the unfolding for @par@.
-
-<sect2>The @errorIO#@ primitive operation
-<p>
-<nidx>errors, primitive</nidx>
-
-The @errorIO#@ primitive takes an argument much like @IO@. It aborts
-execution of the current program, and continues instead by performing
-the given @IO@-like value on the current state of the world.
-
-<tscreen><verb>
-errorIO# :: (State# RealWorld# -> a) -> a
-</verb></tscreen>
-<ncdx>errorIO#</ncdx>
-
-<sect1>GHC/Hugs Extension Libraries
-<p>
-
-The extension libraries provided by both GHC and Hugs are described in
-the <htmlurl name="GHC/Hugs Extension Libraries" url="libs.html">
-document.
-
-<sect1>GHC-only Extension Libraries
-<p>
-<nidx>libraries, ghc-only</nidx>
-<nidx>extension libraries, ghc-only</nidx>
-
-If you rely on the implicit @import Prelude@ that GHC normally does
-for you, and if you don't use any weird flags (notably
-@-fglasgow-exts@), and if you don't import the Glasgow extensions
-interface, @GlaExts@, then GHC should work <em>exactly</em> as the
-Haskell report says (modulo a few minor issues, see Section <ref
-id="vs-Haskell-defn" name="Language Non-compliance">).
-
-If you turn on @-fglasgow-exts@, the compiler will recognise and parse
-unboxed values properly, and provide access to the various interfaces
-libraries described here.
-
-<sect2>The @GlaExts@ interface
-<p>
-<nidx>GlaExts interface (GHC extensions)</nidx>
-
-The @GlaExts@ interface provides access to extensions that only GHC
-implements. These currently are: unboxed types, including the
-representations of the primitive types (Int, Float, etc.), and the
-GHC primitive operations (@+#@, @==#@, etc.).
-
-This module used to provide access to all the Glasgow extensions, but
-these have since been moved into separate libraries for compatibility
-with Hugs (version 2.09: in fact, you can still get at this stuff via
-@GlaExts@ for compatibility, but this facility will likely be removed
-in the future).
-
-<tscreen><verb>
--- the representation of some basic types:
-data Char = C# Char#
-data Int = I# Int#
-data Addr = A# Addr#
-data Word = W# Word#
-data Float = F# Float#
-data Double = D# Double#
-data Integer = J# Int# Int# ByteArray#
-
-module GHC -- all primops and primitive types.
-</verb></tscreen>
-
-<sect2>The @MutableArray@ interface
-<label id="sec:mutable-array">
-<p>
-<nidx>MutableArray interface (GHC extensions)</nidx>
-
-The @MutableArray@ interface defines a general set of operations over
-mutable arrays (@MutableArray@) and mutable chunks of memory
-(@MutableByteArray@):
-
-<tscreen><verb>
-data MutableArray s ix elt -- abstract
-data MutableByteArray s ix -- abstract
- -- instance of : CCallable
--- Creators:
-newArray :: Ix ix => (ix,ix) -> elt -> ST s (MutableArray s ix elt)
-newCharArray :: Ix ix => (ix,ix) -> ST s (MutableByteArray s ix)
-newAddrArray :: Ix ix => (ix,ix) -> ST s (MutableByteArray s ix)
-newIntArray :: Ix ix => (ix,ix) -> ST s (MutableByteArray s ix)
-newFloatArray :: Ix ix => (ix,ix) -> ST s (MutableByteArray s ix)
-newDoubleArray :: Ix ix => (ix,ix) -> ST s (MutableByteArray s ix)
-
-boundsOfArray :: Ix ix => MutableArray s ix elt -> (ix, ix)
-boundsOfByteArray :: Ix ix => MutableByteArray s ix -> (ix, ix)
-
-
-readArray :: Ix ix => MutableArray s ix elt -> ix -> ST s elt
-
-readCharArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Char
-readIntArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Int
-readAddrArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Addr
-readFloatArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Float
-readDoubleArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Double
-
-writeArray :: Ix ix => MutableArray s ix elt -> ix -> elt -> ST s ()
-writeCharArray :: Ix ix => MutableByteArray s ix -> ix -> Char -> ST s ()
-writeIntArray :: Ix ix => MutableByteArray s ix -> ix -> Int -> ST s ()
-writeAddrArray :: Ix ix => MutableByteArray s ix -> ix -> Addr -> ST s ()
-writeFloatArray :: Ix ix => MutableByteArray s ix -> ix -> Float -> ST s ()
-writeDoubleArray :: Ix ix => MutableByteArray s ix -> ix -> Double -> ST s ()
-
-freezeArray :: Ix ix => MutableArray s ix elt -> ST s (Array ix elt)
-freezeCharArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
-freezeIntArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
-freezeAddrArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
-freezeFloatArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
-freezeDoubleArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
-
-unsafeFreezeArray :: Ix ix => MutableArray s ix elt -> ST s (Array ix elt)
-unsafeFreezeByteArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
-thawArray :: Ix ix => Array ix elt -> ST s (MutableArray s ix elt)
-</verb></tscreen>
-
-%ToDo: index these.
-
-<sect2>The @ByteArray@ interface
-<label id="sec:byte-array">
-<p>
-<nidx>ByteArray interface (GHC extensions)</nidx>
-
-@ByteArray@s are chunks of immutable Haskell heap:
-
-<tscreen><verb>
-data ByteArray ix -- abstract
- -- instance of: CCallable
-
-indexCharArray :: Ix ix => ByteArray ix -> ix -> Char
-indexIntArray :: Ix ix => ByteArray ix -> ix -> Int
-indexAddrArray :: Ix ix => ByteArray ix -> ix -> Addr
-indexFloatArray :: Ix ix => ByteArray ix -> ix -> Float
-indexDoubleArray :: Ix ix => ByteArray ix -> ix -> Double
-
-indexCharOffAddr :: Addr -> Int -> Char
-indexIntOffAddr :: Addr -> Int -> Int
-indexAddrOffAddr :: Addr -> Int -> Addr
-indexFloatOffAddr :: Addr -> Int -> Float
-indexDoubleOffAddr :: Addr -> Int -> Double
-</verb></tscreen>
-
-<sect2>Stable pointers
-<p>
-
-Nothing exciting here, just simple boxing up.
-<tscreen><verb>
-data StablePtr a = StablePtr (StablePtr# a)
-
-makeStablePointer :: a -> StablePtr a
-freeStablePointer :: StablePtr a -> IO ()
-</verb></tscreen>
-
-<sect2>Foreign objects
-<label id="sec:foreign-obj">
-<p>
-<nidx>Foreign objects</nidx>
-
-This module provides the @ForeignObj@ type and wrappers around the
-primitive operations on foreign objects.
-
-<tscreen><verb>
-data ForeignObj = ForeignObj ForeignObj#
-
-makeForeignObj
- :: Addr -- object to be boxed up as a ForeignObj
- -> Addr -- finaliser
- -> IO ForeignObj
-
-writeForeignObj
- :: ForeignObj -- previously created foreign object
- -> Addr -- new value
- -> IO ()
-
-</verb></tscreen>
-<ncdx>ForeignObj</ncdx>
-<ncdx>makeForeignObj</ncdx>
-<ncdx>writeForeignObj</ncdx>
-
-A typical use of @ForeignObj@ is in constructing Haskell bindings
-to external libraries. A good example is that of writing a binding to
-an image-processing library (which was actually the main motivation
-for implementing @ForeignObj@'s precursor, @MallocPtr#@). The
-images manipulated are not stored in the Haskell heap, either because
-the library insist on allocating them internally or we (sensibly)
-decide to spare the GC from having to heave heavy images around.
-
-<tscreen><verb>
-data Image = Image ForeignObj
-</verb></tscreen>
-
-The @ForeignObj@ type is then used to refer to the externally
-allocated image, and to acheive some type safety, the Haskell binding
-defines the @Image@ data type. So, a value of type @ForeignObj@ is
-used to ``box'' up an external reference into a Haskell heap object
-that we can then indirectly reference:
-
-<tscreen><verb>
-createImage :: (Int,Int) -> IO Image
-</verb></tscreen>
-
-So far, this looks just like an @Addr@ type, but @ForeignObj@ offers a
-bit more, namely that we can specify a <em>finalisation routine</em> to
-invoke when the @ForeignObj@ is discarded by the GC. The garbage
-collector invokes the finalisation routine associated with the
-@ForeignObj@, saying `` Thanks, I'm through with this now..'' For the
-image-processing library, the finalisation routine could for the
-images free up memory allocated for them. The finalisation routine has
-currently to be written in C (the finalisation routine can in turn
-call on @FreeStablePtr@ to deallocate a stable pointer).
-
-Associating a finalisation routine with an external object is done by
-calling @makeForeignObj@. {\bf Note:} the foreign object value and
-its finaliser are contained in the @ForeignObj@, so there's no danger
-of an aggressive optimiser somehow separating the two (with the result
-that the foreign reference would not be freed).
-
-(Implementation: a linked list of all @ForeignObj#@s is maintained to
- allow the garbage collector to detect when a @ForeignObj#@ becomes
- garbage.)
-
-Like @Array@, @ForeignObj#@s are represented by heap objects.
-
-Upon controlled termination of the Haskell program, all @ForeignObjs@
-are freed, invoking their respective finalisers before terminating.
-
-<sect2>The @CCall@ module
-<p>
-
-The @CCall@ module defines the classes @CCallable@ and @CReturnable@,
-along with instances for the primitive types (@Int@, @Int#@, @Float@,
-@Float#@ etc.) GHC knows to import this module if you use @_ccall_@,
-but if you need to define your own instances of these classes, you
-will need to import @CCall@ explicitly.
-
-More information on how to use @_ccall_@ can be found in Section
-<ref name="Calling~C directly from Haskell" id="glasgow-ccalls">.
-