[project @ 1997-11-25 13:07:29 by simonm]
[ghc-hetmet.git] / ghc / docs / users_guide / libraries.lit
index 891d9b1..ae5e37f 100644 (file)
-%************************************************************************
-%*                                                                      *
-\section[syslibs]{System libraries}
-\index{system libraries}
-\index{libraries, system}
-%*                                                                      *
-%************************************************************************
-
-We intend to provide more and more ready-to-use Haskell code, so that
-every program doesn't have to invent everything from scratch.
-
-If you provide a \tr{-syslib <name>}\index{-syslib <name> option} option,
-then the interfaces for that library will come into scope (and may be
-\tr{import}ed), and the code will be added in at link time.
-
-We supply a part of the HBC library (\tr{-syslib hbc}); as well as one
-of our own (\tr{-syslib ghc}); one for an interface to POSIX routines
-(\tr{-syslib posix}); and one of contributed stuff off the net, mostly
-numerical (\tr{-syslib contrib}).
-
-If you have Haggis (our GUI X~toolkit for Haskell), it probably works
-with a \tr{-syslib haggis} flag.
-
-%************************************************************************
-%*                                                                      *
-\subsection[GHC-library]{The GHC system library}
-\index{library, GHC}
-\index{GHC library}
-%*                                                                      *
-%************************************************************************
-
-We have started to put together a ``GHC system library.''
-
-At the moment, the library is made of generally-useful bits of the
-compiler itself.
-
-To use this library, just give a \tr{-syslib ghc}\index{-syslib ghc option}
-option to GHC, both for compiling and linking.
-
-%************************************************************************
-%*                                                                      *
-\subsubsection[Bag]{The @Bag@ type}
-\index{Bag module (GHC syslib)}
-%*                                                                      *
-%************************************************************************
-
-A {\em bag} is an unordered collection of elements which may contain
-duplicates.  To use, \tr{import Bag}.
+\begin{onlystandalone}
+\documentstyle[a4wide,grasp]{article}
+\begin{rawlatex}
+\renewcommand{\textfraction}{0.1}
+\renewcommand{\floatpagefraction}{0.9}
+\renewcommand{\dblfloatpagefraction}{0.9}
+
+\sloppy
+\renewcommand{\today}{November 1997}
+\end{rawlatex}
+
+\begin{document}
+\title{The GHC Prelude and Libraries}
+\author{Simon L Peyton Jones \and Simon Marlow \and Will Partain}
+
+\maketitle
+\begin{rawlatex}
+\tableofcontents
+\end{rawlatex}
+\end{onlystandalone}
+
+\section[ghc-prelude]{The GHC prelude and libraries}
+
+This document describes GHC's prelude and libraries.  The basic story is that of
+the Haskell 1.4 Report and Libraries document (which we do not reproduce here),
+but this document describes in addition:
+\begin{itemize}
+\item  GHC's additional non-standard libraries and types, such as
+        state transformers, packed strings, foreign objects, stable
+       pointers, and so on.
+
+\item  GHC's primitive types and operations.  The standard Haskell
+        functions are implemented on top of these, and it is sometimes
+       useful to use them directly.
+
+\item  The organisation of these libraries into directories.
+\item   Short description of programmer interface to the non-standard,
+        `built-in' libraries provided in addition to the standard
+        prelude and libraries.
+\end{itemize}
+
+In addition to the GHC prelude libraries, GHC comes with a number of
+system libraries, which are presented in Section \ref{syslibs}.
+
+\subsection{Prelude library organisation}
+
+{\em Probably only of interest to implementors...}
+
+The prelude libraries are organised into the following three groups,
+each of which is kept in a separate sub-directory of GHC's source
+@lib/@ directory: 
+\begin{description}
+\item[@lib/required/@]  These are the libraries {\em required} by the
+Haskell definition.  All are defined by the Haskell Report, or by the
+Haskell Libraries Report. 
+They currently comprise:
+\begin{itemize}
+\item @Array@: monolithic arrays.
+\item @Char@: more functions on characters.
+\item @Complex@: interface defining complex number type and functions
+over it.
+\item @CPUTime@: get the CPU time used by the program.
+\item @Directory@: basic functions for accessing the file system.
+\item @Ix@: the @Ix@ class of indexing operations.
+\item @IO@: additional input/output functions.
+\item @List@: more functions on lists.
+\item @Locale@: localisation functions.
+\item @Maybe@: more functions on @Maybe@ types.
+\item @Monad@: functions on monads.
+\item @Numeric@: operations for reading and showing number values.
+\item @Prelude@: standard prelude interface.
+\item @Random@: pseudo-random number generator.
+\item @Ratio@: functions on rational numbers.
+\item @System@: basic operating-system interface functions.
+\item @Time@: operations on time.
+\end{itemize}
+
+\item[@lib/glaExts@]  Extension libraries, currently comprising:
+\begin{itemize}
+\item @Addr@: primitive pointer type.
+\item @Bits@: a class of bitwise operations.
+\item @ByteArray@: operations over immutable chunks of (heap allocated) bytes.
+\item @CCall@: classes @CCallable@ and @CReturnable@ for calling C.
+\item @Foreign@: types and operations for GHC's foreign-language
+interface.
+\item @GlaExts@: interface for extensions that are only implemented in
+GHC: namely unboxed types and primitive operations.
+\item @IOExts@: extensions to the @IO@ library.
+\item @Int@: 8, 16, 32 and 64-bit integers with bit operations.
+\item @LazyST@: a lazy version of the @ST@ monad.
+\item @MutableArray@: operations over mutable arrays.
+\item @ST@: the state transformer monad, @STRef@s and @STArray@s.
+\item @Word@: 8, 16, 32 and 64-bit naturals with bit operations.
+\end{itemize}
+
+\item[@lib/concurrent@] GHC extension libraries to support Concurrent Haskell, currently comprising:
+\begin{itemize}
+\item @Concurrent@: main library.
+\item @Parallel@: stuff for multi-processor parallelism.
+\item @Channel@
+\item @ChannelVar@
+\item @Merge@
+\item @SampleVar@
+\item @Semaphore@
+\end{itemize}
+
+\item[@lib/ghc@] These libraries are the pieces on which all the
+others are built.  They aren't typically imported by Joe Programmer,
+but there's nothing to stop you doing so if you want.  In general, the
+modules prefixed by @Prel@ are pieces that go towards building
+@Prelude@.
+
+\begin{itemize}
+\item @GHC@: this ``library'' brings into scope all the primitive
+types and operations, such as @Int#@, @+#@, @encodeFloat#@, etc etc.
+It is unique in that there is no Haskell source code for it.  Details
+in Section \ref{sect:ghc}.
+
+\item @PrelBase@: defines the basic types and classes without which
+very few Haskell programs can work.  The classes are: @Eq@, @Ord@,
+@Enum@, @Bounded@, @Num@, @Show@, @Eval@, @Monad@, @MonadZero@,
+@MonadPlus@.  The types are: list, @Bool@, @Char@, @Ordering@,
+@String@, @Int@, @Integer@.
+
+\item @PrelMaybe@: defines the @Maybe@ type.
+
+\item @PrelEither@: defines the @Either@ type.
+
+\item @PrelTup@: defines tuples and their instances.
+
+\item @PrelList@: defines most of the list operations required by
+@Prelude@.  (A few are in @PrelBase@, to avoid gratuitous mutual
+recursion between modules.)
+
+\item @PrelNum@ defines: the numeric classes beyond @Num@, namely
+@Real@, @Integral@, @Fractional@, @Floating@, @RealFrac@, @RealFloat@;
+instances for appropriate classes for @Int@ and @Integer@; the types
+@Float@, @Double@, and @Ratio@ and their instances.
+
+\item @PrelRead@: the @Read@ class and all its instances.  It's kept
+separate because many programs don't use @Read@ at all, so we don't
+even want to link in its code. (If the prelude libraries are built by
+splitting the object files, this is all a non-issue)
+
+\item @ConcBase@: substrate stuff for Concurrent Haskell.
+
+\item @IOBase@: substrate stuff for the main I/O libraries.
+\item @IOHandle@: large blob of code for doing I/O on handles.
+\item @PrelIO@: the remaining small pieces to produce the I/O stuff
+needed by @Prelude@.
+
+\item @STBase@: substrate stuff for @ST@.
+\item @ArrBase@: substrate stuff for @Array@.
+
+\item @GHCerr@: error reporting code, called from code that the
+compiler plants in compiled programs.
+
+\item @GHCmain@: the definition of @mainIO@, which is what {\em
+       really} gets called by the runtime system.  @mainIO@ in turn
+       calls @main@.
+
+\item @PackBase@: low-level packing/unpacking operations.
+
+\item @Error@: the definition of @error@, placed in its own module
+with a hand-written @.hi-boot@ file in order to break recursive
+dependencies in the libraries (everything needs @error@, but the
+definition of @error@ itself needs a few things...).
+\end{itemize}
+\end{description}
+
+The @...Base@ modules generally export representation information that
+is hidden from the public interface.  For example the module @STBase@
+exports the type @ST@ including its representation, whereas the module
+@ST@ exports @ST@ abstractly.
+
+None of these modules are involved in any mutual recursion, with the
+sole exception that many modules import @Error.error@.
+
+\subsection[ghc-libs-ghc]{The module @GHC@: really primitive stuff}
+\label{sect:ghc}
+
+This section 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.
 
+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.
+
+\subsubsection{Character and numeric types}
+
+There are the following obvious primitive types:
 \begin{verbatim}
-emptyBag        :: Bag elt
-unitBag         :: elt -> Bag elt
-
-unionBags       :: Bag elt   -> Bag elt -> Bag elt
-unionManyBags   :: [Bag elt] -> Bag elt
-consBag                :: elt       -> Bag elt -> Bag elt
-snocBag         :: Bag elt   -> elt     -> Bag elt
-
-concatBag      :: Bag (Bag a) -> Bag a
-mapBag         :: (a -> b) -> Bag a -> Bag b
-
-foldBag :: (r -> r -> r) -- Replace TwoBags with this; should be associative
-       -> (a -> r)      -- Replace UnitBag with this
-       -> r             -- Replace EmptyBag with this
-       -> Bag a
-       -> r
-
-elemBag         :: Eq elt => elt -> Bag elt -> Bool
-isEmptyBag      ::                  Bag elt -> Bool
-filterBag       :: (elt -> Bool) -> Bag elt -> Bag elt
-partitionBag    :: (elt -> Bool) -> Bag elt-> (Bag elt, Bag elt)
-        -- returns the elements that do/don't satisfy the predicate
-
-listToBag       :: [elt] -> Bag elt
-bagToList       :: Bag elt -> [elt]
+type Char#
+type Int#      -- see also Word# and Addr#, later
+type Float#
+type Double#
 \end{verbatim}
+If you really want to know their exact equivalents in C, see
+@ghc/includes/StgTypes.lh@ in the GHC source tree.
 
-%************************************************************************
-%*                                                                      *
-\subsubsection[BitSet]{The @BitSet@ type}
-\index{BitSet module (GHC syslib)}
-%*                                                                      *
-%************************************************************************
+Literals for these types may be written as follows:
+\begin{verbatim}
+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 *')
+\end{verbatim}
 
-Bit sets are a fast implementation of sets of integers ranging from 0
-to one less than the number of bits in a machine word (typically 31).
-If any element exceeds the maximum value for a particular machine
-architecture, the results of these operations are undefined.  You have
-been warned.  [``If you put any safety checks in this code, I will have
-to kill you.'' --JSM]
+\subsubsubsection{Comparison operations}
+\begin{verbatim}
+{>,>=,==,/=,<,<=}# :: Int# -> Int# -> Bool
 
+{gt,ge,eq,ne,lt,le}Char# :: Char# -> Char# -> Bool
+    -- ditto for Word#, Float#, Double#, and Addr#
+\end{verbatim}
+
+\subsubsubsection{Unboxed-character operations}
 \begin{verbatim}
-mkBS        :: [Int]  -> BitSet
-listBS      :: BitSet -> [Int]
-emptyBS     :: BitSet 
-unitBS     :: Int    -> BitSet
+ord# :: Char# -> Int#
+chr# :: Int# -> Char#
+\end{verbatim}
 
-unionBS     :: BitSet -> BitSet -> BitSet
-minusBS     :: BitSet -> BitSet -> BitSet
-elementBS   :: Int    -> BitSet -> Bool
-intersectBS :: BitSet -> BitSet -> BitSet
 
-isEmptyBS   :: BitSet -> Bool
+\subsubsubsection{Unboxed-@Int@ operations}
+\begin{verbatim}
+{+,-,*,quotInt,remInt}# :: Int# -> Int# -> Int#
+negateInt# :: Int# -> Int#
+
+iShiftL#, iShiftRA#, iShiftRL# :: Int# -> Int# -> Int#
+       -- shift left, right arithmetic, right logical
 \end{verbatim}
 
-%************************************************************************
-%*                                                                      *
-\subsubsection[FiniteMap]{The @FiniteMap@ type}
-\index{FiniteMap module (GHC syslib)}
-%*                                                                      *
-%************************************************************************
+{\bf Note:} No error/overflow checking!
 
-What functional programmers call a {\em finite map}, everyone else
-calls a {\em lookup table}.
+\subsubsubsection{Unboxed-@Double@ and @Float@ operations}
+\begin{verbatim}
+{plus,minus,times,divide}Double# :: Double# -> Double# -> Double#
+negateDouble# :: Double# -> Double#
+
+float2Int#     :: Double# -> Int#   -- just a cast, no checking!
+int2Double#    :: Int# -> Double#
+
+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#
+\end{verbatim}
 
-Out code is derived from that in this paper:
-\begin{display}
-S Adams
-"Efficient sets: a balancing act"
-Journal of functional programming 3(4) Oct 1993, pages 553-562
-\end{display}
-Guess what?  The implementation uses balanced trees.
+There's an exactly-matching set of unboxed-@Float@ ops; replace
+@Double#@ with @Float#@ in the list above.  There are two
+coercion functions for @Float#@/@Double#@:
+\begin{verbatim}
+float2Double#  :: Float# -> Double#
+double2Float#  :: Double# -> Float#
+\end{verbatim}
 
+The primitive versions of @encodeDouble@/@decodeDouble@:
 \begin{verbatim}
---      BUILDING
-emptyFM         :: FiniteMap key elt
-unitFM         :: key -> elt -> FiniteMap key elt
-listToFM        :: Ord key => [(key,elt)] -> FiniteMap key elt
-                        -- In the case of duplicates, the last is taken
-
---      ADDING AND DELETING
-                   -- Throws away any previous binding
-                   -- In the list case, the items are added starting with the
-                   -- first one in the list
-addToFM         :: Ord key => FiniteMap key elt -> key -> elt  -> FiniteMap key elt
-addListToFM     :: Ord key => FiniteMap key elt -> [(key,elt)] -> FiniteMap key elt
-
-                   -- Combines with previous binding
-addToFM_C       :: Ord key => (elt -> elt -> elt)
-                           -> FiniteMap key elt -> key -> elt  
-                           -> FiniteMap key elt
-addListToFM_C   :: Ord key => (elt -> elt -> elt)
-                           -> FiniteMap key elt -> [(key,elt)] 
-                           -> FiniteMap key elt
-
-                   -- Deletion doesn't complain if you try to delete something
-                   -- which isn't there
-delFromFM       :: Ord key => FiniteMap key elt -> key   -> FiniteMap key elt
-delListFromFM   :: Ord key => FiniteMap key elt -> [key] -> FiniteMap key elt
-
---      COMBINING
-                   -- Bindings in right argument shadow those in the left
-plusFM          :: Ord key => FiniteMap key elt -> FiniteMap key elt
-                           -> FiniteMap key elt
-
-                   -- Combines bindings for the same thing with the given function
-plusFM_C        :: Ord key => (elt -> elt -> elt) 
-                           -> FiniteMap key elt -> FiniteMap key elt -> FiniteMap key elt
-
-minusFM         :: Ord key => FiniteMap key elt -> FiniteMap key elt -> FiniteMap key elt
-                   -- (minusFM a1 a2) deletes from a1 any bindings which are bound in a2
-
-intersectFM     :: Ord key => FiniteMap key elt -> FiniteMap key elt -> FiniteMap key elt 
-intersectFM_C   :: Ord key => (elt -> elt -> elt)
-                           -> FiniteMap key elt -> FiniteMap key elt -> FiniteMap key elt 
-
---      MAPPING, FOLDING, FILTERING
-foldFM          :: (key -> elt -> a -> a) -> a -> FiniteMap key elt -> a
-mapFM           :: (key -> elt1 -> elt2) -> FiniteMap key elt1 -> FiniteMap key elt2
-filterFM        :: Ord key => (key -> elt -> Bool) 
-                           -> FiniteMap key elt -> FiniteMap key elt
-
---      INTERROGATING
-sizeFM          :: FiniteMap key elt -> Int
-isEmptyFM      :: FiniteMap key elt -> Bool
-
-elemFM         :: Ord key => key -> FiniteMap key elt -> Bool
-lookupFM        :: Ord key => FiniteMap key elt -> key -> Maybe elt
-lookupWithDefaultFM
-                :: Ord key => FiniteMap key elt -> elt -> key -> elt
-                -- lookupWithDefaultFM supplies a "default" elt
-                -- to return for an unmapped key
-
---      LISTIFYING
-fmToList        :: FiniteMap key elt -> [(key,elt)]
-keysFM          :: FiniteMap key elt -> [key]
-eltsFM          :: FiniteMap key elt -> [elt]
+encodeDouble#  :: Int# -> Int# -> ByteArray#   -- Integer mantissa
+               -> Int#                         -- Int exponent
+               -> Double#
+
+decodeDouble#  :: Double# -> PrelNum.ReturnIntAndGMP
 \end{verbatim}
 
-%************************************************************************
-%*                                                                      *
-\subsubsection[ListSetOps]{The @ListSetOps@ type}
-\index{ListSetOps module (GHC syslib)}
-%*                                                                      *
-%************************************************************************
+(And the same for @Float#@s.)
+
+\subsubsection{Operations on/for @Integers@ (interface to GMP)}
+\label{sect:horrid-Integer-pairing-types}
 
-Just a few set-sounding operations on lists.  If you want sets, use
-the \tr{Set} module.
+We implement @Integers@ (arbitrary-precision integers) using the GNU
+multiple-precision (GMP) package (version 1.3.2).
 
+{\bf Note:} some of this might change when we upgrade to using GMP~2.x.
+
+The data type for @Integer@ must mirror that for @MP_INT@ in @gmp.h@
+(see @gmp.info@ in \tr{ghc/includes/runtime/gmp}).  It comes out as:
 \begin{verbatim}
-unionLists          :: Eq a => [a] -> [a] -> [a]
-intersectLists      :: Eq a => [a] -> [a] -> [a]
-minusList           :: Eq a => [a] -> [a] -> [a]
-disjointLists       :: Eq a => [a] -> [a] -> Bool
-intersectingLists   :: Eq a => [a] -> [a] -> Bool
+data Integer = J# Int# Int# ByteArray#
 \end{verbatim}
 
-%************************************************************************
-%*                                                                      *
-\subsubsection[Maybes]{The @Maybes@ type}
-\index{Maybes module (GHC syslib)}
-%*                                                                      *
-%************************************************************************
+So, @Integer@ is really just a ``pairing'' type for a particular
+collection of primitive types.
 
-The \tr{Maybe} type itself is in the Haskell~1.3 prelude.  Moreover,
-the required \tr{Maybe} library provides many useful functions on
-\tr{Maybe}s.  This (old) module provides more.
+The operations in the GMP return other combinations of
+GMP-plus-something, so we need ``pairing'' types for those, too:
+\begin{verbatim}
+data Return2GMPs     = Return2GMPs Int# Int# ByteArray# Int# Int# ByteArray#
+data ReturnIntAndGMP = ReturnIntAndGMP Int# Int# Int# ByteArray#
 
-An \tr{Either}-like type called \tr{MaybeErr}:
+-- ????? something to return a string of bytes (in the heap?)
+\end{verbatim}
+
+The primitive ops to support @Integers@ use the ``pieces'' of the
+representation, and are as follows:
 \begin{verbatim}
-data MaybeErr val err = Succeeded val | Failed err
+negateInteger# :: Int# -> Int# -> ByteArray# -> Integer
+
+{plus,minus,times}Integer# :: Int# -> Int# -> ByteArray#
+                          -> Int# -> Int# -> ByteArray#
+                          -> Integer
+
+cmpInteger# :: Int# -> Int# -> ByteArray#
+           -> Int# -> Int# -> ByteArray#
+           -> Int# -- -1 for <; 0 for ==; +1 for >
+
+divModInteger#, quotRemInteger#
+       :: Int# -> Int# -> ByteArray#
+       -> Int# -> Int# -> ByteArray#
+       -> PrelNum.Return2GMPs
+
+integer2Int# :: Int# -> 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.
 \end{verbatim}
 
-Some operations to do with \tr{Maybe} (some commentary follows):
+
+\subsubsection{Words and addresses}
+
+A @Word#@ is used for bit-twiddling operations.  It is the same size as
+an @Int#@, but has no sign nor any arithmetic operations.
 \begin{verbatim}
-maybeToBool :: Maybe a -> Bool      -- Nothing => False; Just => True
-allMaybes   :: [Maybe a] -> Maybe [a]
-firstJust   :: [Maybe a] -> Maybe a
-findJust    :: (a -> Maybe b) -> [a] -> Maybe b
-
-assocMaybe  :: Eq a => [(a,b)] -> a -> Maybe b
-mkLookupFun :: (key -> key -> Bool) -- Equality predicate
-            -> [(key,val)]          -- The assoc list
-            -> (key -> Maybe val)   -- A lookup fun to use
-mkLookupFunDef :: (key -> key -> Bool) -- Ditto, with a default
-            -> [(key,val)]
-           -> val                  -- the default
-            -> (key -> val)        -- NB: not a Maybe anymore
-
-    -- a monad thing
-thenMaybe   :: Maybe a -> (a -> Maybe b) -> Maybe b
-returnMaybe :: a -> Maybe a
-failMaybe   :: Maybe a
-mapMaybe    :: (a -> Maybe b) -> [a] -> Maybe [b]
+type Word#     -- Same size/etc as Int# but *unsigned*
+type Addr#     -- A pointer from outside the "Haskell world" (from C, probably);
+               -- described under "arrays"
 \end{verbatim}
 
-NB: @catMaybes@, which used to be here, is in the Haskell~1.3 libraries.
+@Word#@s and @Addr#@s have the usual comparison operations.
+Other unboxed-@Word@ ops (bit-twiddling and coercions):
+\begin{verbatim}
+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.
 
-@allMaybes@ collects a list of @Justs@ into a single @Just@, returning
-@Nothing@ if there are any @Nothings@.
+not# :: Word# -> Word#
 
-@firstJust@ takes a list of @Maybes@ and returns the
-first @Just@ if there is one, or @Nothing@ otherwise.
+shiftL#, shiftRA#, shiftRL# :: Word# -> Int# -> Word#
+       -- shift left, right arithmetic, right logical
 
-@assocMaybe@ looks up in an association list, returning
-@Nothing@ if it fails.
+int2Word#      :: Int#  -> Word# -- just a cast, really
+word2Int#      :: Word# -> Int#
+\end{verbatim}
 
-Now, some operations to do with \tr{MaybeErr} (comments follow):
+Unboxed-@Addr@ ops (C casts, really):
 \begin{verbatim}
-    -- a monad thing (surprise, surprise)
-thenMaB   :: MaybeErr a err -> (a -> MaybeErr b err) -> MaybeErr b err
-returnMaB :: val -> MaybeErr val err
-failMaB   :: err -> MaybeErr val err
-
-listMaybeErrs :: [MaybeErr val err] -> MaybeErr [val] [err]
-foldlMaybeErrs :: (acc -> input -> MaybeErr acc err)
-               -> acc
-               -> [input]
-               -> MaybeErr acc [err]
+int2Addr#      :: Int#  -> Addr#
+addr2Int#      :: Addr# -> Int#
 \end{verbatim}
 
-@listMaybeErrs@ takes a list of @MaybeErrs@ and, if they all succeed,
-returns a @Succeeded@ of a list of their values.  If any fail, it
-returns a @Failed@ of the list of all the errors in the list.
+The casts between @Int#@, @Word#@ and @Addr#@ correspond to null
+operations at the machine level, but are required to keep the Haskell
+type checker happy.
+
+Operations for indexing off of C pointers (@Addr#@s) to snatch values
+are listed under ``arrays''.
 
-@foldlMaybeErrs@ works along a list, carrying an accumulator; it
-applies the given function to the accumulator and the next list item,
-accumulating any errors that occur.
+\subsubsection{Arrays}
 
-%************************************************************************
-%*                                                                      *
-\subsubsection[PackedString]{The @PackedString@ type}
-\index{PackedString module (GHC syslib)}
-%*                                                                      *
-%************************************************************************
+The type @Array# elt@ is the type of primitive, unboxed arrays of
+values of type @elt@.
 
-You need \tr{import PackedString}, and
-heave in your \tr{-syslib ghc}.
+\begin{verbatim}
+type Array# elt
+\end{verbatim}
+
+@Array#@ is more primitive than a Haskell array --- indeed, the
+Haskell @Array@ interface is implemented using @Array#@ --- in that an
+@Array#@ is indexed only by @Int#@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 @Array#@ are themselves boxed.
+
+The type @ByteArray#@ is similar to @Array#@, except that it contains
+just a string of (non-pointer) bytes.
 
-The basic type and functions which are available are:
 \begin{verbatim}
-data PackedString
-
-packString      :: [Char] -> PackedString
-packStringST    :: [Char] -> ST s PackedString
-packCString     :: Addr  -> PackedString
-packCBytes      :: Int -> Addr -> PackedString
-packCBytesST    :: Int -> Addr -> ST s PackedString
-packBytesForC   :: [Char] -> ByteArray Int
-packBytesForCST :: [Char] -> ST s (ByteArray Int)
-byteArrayToPS   :: ByteArray Int -> PackedString
-psToByteArray   :: PackedString -> ByteArray Int
-
-unpackPS        :: PackedString -> [Char]
+type ByteArray#
 \end{verbatim}
 
-We also provide a wad of list-manipulation-like functions:
+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, @ByteArray#@ is deliberately
+a bit vague about the type of its components.  Operations are provided
+to extract values of type @Char#@, @Int#@, @Float#@, @Double#@, and
+@Addr#@ from arbitrary offsets within a @ByteArray#@.  (For type
+@Foo#@, the $i$th offset gets you the $i$th @Foo#@, not the @Foo#@ at
+byte-position $i$.  Mumble.)  (If you want a @Word#@, grab an @Int#@,
+then coerce it.)
+
+Lastly, we have static byte-arrays, of type @Addr#@ [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 @ByteArray#@.  They
+are only needed in order to pass values from C to Haskell.
+
+\subsubsubsection{Reading and writing.}
+
+Primitive arrays are linear, and indexed starting at zero.
+
+The size and indices of a @ByteArray#@, @Addr#@, and
+@MutableByteArray#@ 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 @ByteArray#@ 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)
+
+{\em Should we provide some @sizeOfDouble#@ constants?}
+
+Out-of-range errors on indexing should be caught by the code which
+uses the primitive operation; the primitive operations themselves do
+{\em not} check for out-of-range indexes. The intention is that the
+primitive ops compile to one machine instruction or thereabouts.
+
+We use the terms ``reading'' and ``writing'' to refer to accessing
+{\em mutable} arrays (see Section~\ref{sect:mutable}), and
+``indexing'' to refer to reading a value from an {\em immutable}
+array.
+
+Immutable byte arrays are straightforward to index (all indices in bytes):
 \begin{verbatim}
-nilPS      :: PackedString
-consPS     :: Char -> PackedString -> PackedString
-
-headPS     :: PackedString -> Char
-tailPS     :: PackedString -> PackedString
-nullPS     :: PackedString -> Bool
-appendPS   :: PackedString -> PackedString -> PackedString
-lengthPS   :: PackedString -> Int
-indexPS    :: PackedString -> Int -> Char
-           -- 0-origin indexing into the string
-mapPS      :: (Char -> Char) -> PackedString -> PackedString {-or String?-}
-filterPS   :: (Char -> Bool) -> PackedString -> PackedString {-or String?-}
-foldlPS    :: (a -> Char -> a) -> a -> PackedString -> a
-foldrPS    :: (Char -> a -> a) -> a -> PackedString -> a
-takePS     :: Int -> PackedString -> PackedString
-dropPS     :: Int -> PackedString -> PackedString
-splitAtPS  :: Int -> PackedString -> (PackedString, PackedString)
-takeWhilePS:: (Char -> Bool) -> PackedString -> PackedString
-dropWhilePS:: (Char -> Bool) -> PackedString -> PackedString
-spanPS     :: (Char -> Bool) -> PackedString -> (PackedString, PackedString)
-breakPS    :: (Char -> Bool) -> PackedString -> (PackedString, PackedString)
-linesPS    :: PackedString -> [PackedString]
-wordsPS    :: PackedString -> [PackedString]
-reversePS  :: PackedString -> PackedString
-concatPS   :: [PackedString] -> PackedString
-
-substrPS   :: PackedString -> Int -> Int -> PackedString
-           -- pluck out a piece of a PS
-           -- start and end chars you want; both 0-origin-specified
+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
+\end{verbatim}
+\index{indexCharArray# function}
+\index{indexIntArray# function}
+\index{indexAddrArray# function}
+\index{indexFloatArray# function}
+\index{indexDoubleArray# function}
+\index{indexCharOffAddr# function}
+\index{indexIntOffAddr# function}
+\index{indexFloatOffAddr# function}
+\index{indexDoubleOffAddr# function}
+\index{indexAddrOffAddr# function}
+
+The last of these, @indexAddrOffAddr#@, extracts an @Addr#@ using an offset
+from another @Addr#@, thereby providing the ability to follow a chain of
+C pointers.
+
+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 lifted value, but I don't like it!
+\begin{verbatim}
+indexArray#       :: Array# elt -> Int# -> PrelBase.Lift elt  -- Yuk!
 \end{verbatim}
 
-%************************************************************************
-%*                                                                      *
-\subsubsection[Pretty]{The @Pretty@ type}
-\index{Pretty module (GHC syslib)}
-%*                                                                      *
-%************************************************************************
 
-This is the pretty-printer that we use in GHC.
+\subsubsection{The state type}
+\index{State# type}
 
+The primitive type @State#@ 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 {\em only}
+effect of this parameterisation is in the type system: all values of type
+@State#@ 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.
 \begin{verbatim}
-type Pretty
-
-ppShow          :: Int{-width-} -> Pretty -> [Char]
-
-pp'SP           :: Pretty -- "comma space"
-ppComma         :: Pretty -- ,
-ppEquals        :: Pretty -- =
-ppLbrack        :: Pretty -- [
-ppLparen        :: Pretty -- (
-ppNil           :: Pretty -- nothing
-ppRparen        :: Pretty -- )
-ppRbrack        :: Pretty -- ]
-ppSP            :: Pretty -- space
-ppSemi          :: Pretty -- ;
-
-ppChar          :: Char -> Pretty
-ppDouble        :: Double -> Pretty
-ppFloat         :: Float -> Pretty
-ppInt           :: Int -> Pretty
-ppInteger       :: Integer -> Pretty
-ppRational      :: Rational -> Pretty
-ppStr           :: [Char] -> Pretty
-
-ppAbove         :: Pretty -> Pretty -> Pretty
-ppAboves        :: [Pretty] -> Pretty
-ppBeside        :: Pretty -> Pretty -> Pretty
-ppBesides       :: [Pretty] -> Pretty
-ppCat           :: [Pretty] -> Pretty
-ppHang          :: Pretty -> Int -> Pretty -> Pretty
-ppInterleave    :: Pretty -> [Pretty] -> Pretty -- spacing between
-ppIntersperse   :: Pretty -> [Pretty] -> Pretty -- no spacing between
-ppNest          :: Int -> Pretty -> Pretty
-ppSep           :: [Pretty] -> Pretty
-
-ppBracket      :: Pretty -> Pretty -- [ ... ] around something
-ppParens       :: Pretty -> Pretty -- ( ... ) around something
-ppQuote        :: Pretty -> Pretty -- ` ... ' around something
+type State# s
 \end{verbatim}
 
-%************************************************************************
-%*                                                                      *
-\subsubsection[Set]{The @Set@ type}
-\index{Set module (GHC syslib)}
-%*                                                                      *
-%************************************************************************
 
-Our implementation of {\em sets} (key property: no duplicates) is just
-a variant of the \tr{FiniteMap} module.
+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!} Its only role in life is to be
+the type which distinguishes the @IO@ state transformer.
+\begin{verbatim}
+data RealWorld
+\end{verbatim}
+
+\subsubsubsection{State of the world}
 
+A single, primitive, value of type @State# RealWorld@ is provided.
 \begin{verbatim}
-mkSet           :: Ord a => [a]  -> Set a
-setToList       :: Set a -> [a]
-emptySet        :: Set a
-singletonSet    :: a -> Set a
-
-union           :: Ord a => Set a -> Set a -> Set a
-unionManySets   :: Ord a => [Set a] -> Set a
-intersect       :: Ord a => Set a -> Set a -> Set a
-minusSet        :: Ord a => Set a -> Set a -> Set a
-mapSet          :: Ord a => (b -> a) -> Set b -> Set a
-
-elementOf       :: Ord a => a -> Set a -> Bool
-isEmptySet      :: Set a -> Bool
+realWorld# :: State# GHC.RealWorld
 \end{verbatim}
+\index{realWorld# state object}
 
-%************************************************************************
-%*                                                                      *
-\subsubsection[Util]{The @Util@ type}
-\index{Util module (GHC syslib)}
-%*                                                                      *
-%************************************************************************
+(Note: in the compiler, not a @PrimOp@; just a mucho magic
+@Id@. Exported from @GHC@, though).
 
-Stuff that has been useful to use in writing the compiler.  Don't be
-too surprised if this stuff moves/gets-renamed/etc.
+\subsubsection{State pairing types}
+\label{sect: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.
 \begin{verbatim}
--- general list processing
-exists          :: (a -> Bool) -> [a] -> Bool
-forall          :: (a -> Bool) -> [a] -> Bool
-isSingleton     :: [a] -> Bool
-lengthExceeds   :: [a] -> Int -> Bool
-mapAndUnzip    :: (a -> (b, c)) -> [a] -> ([b], [c])
-mapAndUnzip3   :: (a -> (b, c, d)) -> [a] -> ([b], [c], [d])
-nOfThem         :: Int -> a -> [a]
-zipEqual        :: [a] -> [b] -> [(a,b)]
-zipWithEqual   :: String -> (a->b->c) -> [a]->[b]->[c]
-zipWith3Equal  :: String -> (a->b->c->d) -> [a]->[b]->[c]->[d]
-zipWith4Equal  :: String -> (a->b->c->d->e) -> [a]->[b]->[c]->[d]->[e]
-zipLazy                :: [a] -> [b] -> [(a,b)] -- lazy in 2nd arg
-
--- association lists
-assoc       :: Eq a => String -> [(a, b)] -> a -> b
-
--- duplicate handling
-hasNoDups    :: Eq a => [a] -> Bool
-equivClasses :: (a -> a -> Ordering) -> [a] -> [[a]]
-runs         :: (a -> a -> Bool)     -> [a] -> [[a]]
-removeDups   :: (a -> a -> Ordering) -> [a] -> ([a], [[a]])
-
--- sorting (don't complain of no choice...)
-quicksort          :: (a -> a -> Bool)     -> [a] -> [a]
-sortLt             :: (a -> a -> Bool)     -> [a] -> [a]
-stableSortLt       :: (a -> a -> Bool)     -> [a] -> [a]
-mergesort          :: (a -> a -> Ordering) -> [a] -> [a]
-mergeSort          :: Ord a => [a] -> [a]
-naturalMergeSort   :: Ord a => [a] -> [a]
-mergeSortLe        :: Ord a => [a] -> [a]
-naturalMergeSortLe :: Ord a => [a] -> [a]
-
--- transitive closures
-transitiveClosure :: (a -> [a])         -- Successor function
-                  -> (a -> a -> Bool)   -- Equality predicate
-                  -> [a] 
-                  -> [a]                -- The transitive closure
-
--- accumulating (Left, Right, Bi-directional)
-mapAccumL :: (acc -> x -> (acc, y))
-                        -- Function of elt of input list and
-                        -- accumulator, returning new accumulator and
-                        -- elt of result list
-          -> acc        -- Initial accumulator
-          -> [x]        -- Input list
-          -> (acc, [y]) -- Final accumulator and result list
-
-mapAccumR :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
-
-mapAccumB :: (accl -> accr -> x -> (accl, accr,y))
-          -> accl -> accr -> [x]
-          -> (accl, accr, [y])
-
--- comparisons
-cmpString :: String -> String -> Ordering
-
--- pairs
-applyToPair :: ((a -> c), (b -> d)) -> (a, b) -> (c, d)
-applyToFst  :: (a -> c) -> (a, b) -> (c, b)
-applyToSnd  :: (b -> d) -> (a, b) -> (a, d)
-foldPair    :: (a->a->a, b->b->b) -> (a, b) -> [(a, b)] -> (a, b)
-unzipWith   :: (a -> b -> c) -> [(a, b)] -> [c]
+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)
 \end{verbatim}
 
-%************************************************************************
-%*                                                                      *
-\subsection[C-interfaces]{Interfaces to C libraries}
-\index{C library interfaces}
-\index{interfaces, C library}
-%*                                                                      *
-%************************************************************************
+Hideous.
 
-The GHC system library (\tr{-syslib ghc}) also provides interfaces to
-several useful C libraries, mostly from the GNU project.
+\subsubsection{Mutable arrays}
+\label{sect:mutable}
+\index{Mutable arrays}
 
-%************************************************************************
-%*                                                                      *
-\subsubsection[Readline]{The @Readline@ interface}
-\index{Readline library (GHC syslib)}
-\index{command-line editing library}
-%*                                                                      *
-%************************************************************************
+Corresponding to @Array#@ and @ByteArray#@, 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.
+\begin{verbatim}
+type MutableArray# s elt
+type MutableByteArray# s
+\end{verbatim}
 
-(Darren Moffat supplied the \tr{Readline} interface.)
+\subsubsubsection{Allocation}
+\index{Mutable arrays, allocation}
+\index{Allocation, of mutable arrays}
 
-The \tr{Readline} module is a straightforward interface to the GNU
-Readline library.  As such, you will need to look at the GNU
-documentation (and have a \tr{libreadline.a} file around somewhere...)
+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.
 
-You'll need to link any Readlining program with \tr{-lreadline -ltermcap},
-besides the usual \tr{-syslib ghc}.
+\begin{verbatim}
+newArray#       :: Int# -> elt -> State# s -> StateAndMutableArray# s elt 
 
-The main function you'll use is:
+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 
+\end{verbatim}
+
+The size of a @ByteArray#@ is given in bytes.
+
+\subsubsubsection{Reading and writing}
+
+%OLD: Remember, offsets in a @MutableByteArray#@ are in bytes.
 \begin{verbatim}
-readline :: String{-the prompt-} -> IO String
+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 
+
+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 
 \end{verbatim}
 
-If you want to mess around with Full Readline G(l)ory, we also
-provide:
+
+\subsubsubsection{Equality.}
+
+One can take ``equality'' of mutable arrays.  What is compared is the
+{\em name} or reference to the mutable array, not its contents.
 \begin{verbatim}
-rlInitialize, addHistory,
+sameMutableArray#     :: MutableArray# s elt -> MutableArray# s elt -> Bool
+sameMutableByteArray# :: MutableByteArray# s -> MutableByteArray# s -> Bool
+\end{verbatim}
+
+
+\subsubsubsection{Freezing mutable arrays}
+
+Only unsafe-freeze has a primitive.  (Safe freeze is done directly in Haskell 
+by copying the array and then using @unsafeFreeze@.) 
+\begin{verbatim}
+unsafeFreezeArray#     :: MutableArray# s elt -> State# s -> StateAndArray#     s elt
+unsafeFreezeByteArray# :: MutableByteArray# s -> State# s -> StateAndByteArray# s
+\end{verbatim}
+
+
+\subsubsection{Stable pointers}
+\index{Stable pointers}
 
-rlBindKey, rlAddDefun, RlCallbackFunction(..),
+A stable pointer is a name for a Haskell object which can be passed to
+the external world.  It is ``stable'' in the sense that the name does
+not change when the Haskell garbage collector runs --- in contrast to
+the address of the object which may well change.
 
-rlGetLineBuffer, rlSetLineBuffer, rlGetPoint, rlSetPoint, rlGetEnd,
-rlSetEnd, rlGetMark, rlSetMark, rlSetDone, rlPendingInput,
+The stable pointer type is parameterised by the type of the thing
+which is named.
+\begin{verbatim}
+type StablePtr# a
+\end{verbatim}
 
-rlPrompt, rlTerminalName, rlSetReadlineName, rlGetReadlineName
+A stable pointer is represented by an index into the (static)
+@StablePointerTable@.  The Haskell garbage collector treats the
+@StablePointerTable@ as a source of roots for GC.
+
+The @makeStablePointer@ function converts a value into a stable
+pointer.  It is part of the @IO@ monad, because we want to be sure
+we don't allocate one twice by accident, and then only free one of the
+copies.
+\begin{verbatim}
+makeStablePointer#  :: a -> State# RealWorld -> StateAndStablePtr# RealWorld a
+freeStablePointer#  :: StablePtr# a -> State# RealWorld -> State# RealWorld
+deRefStablePointer# :: StablePtr# a -> State# RealWorld -> StateAndPtr RealWorld a
 \end{verbatim}
-(All those names are just Haskellised versions of what you
-will see in the GNU readline documentation.)
-
-%************************************************************************
-%*                                                                      *
-\subsubsection[Regexp]{The @Regexp@ and @MatchPS@ interfaces}
-\index{Regex library (GHC syslib)}
-\index{MatchPS library (GHC syslib)}
-\index{regular-expressions library}
-%*                                                                      *
-%************************************************************************
-
-(Sigbjorn Finne supplied the regular-expressions interface.)
-
-The \tr{Regex} library provides quite direct interface to the GNU
-regular-expression library, for doing manipulation on
-\tr{PackedString}s.  You probably need to see the GNU documentation
-if you are operating at this level.
-
-The datatypes and functions that \tr{Regex} provides are:
+
+There is also a C procedure @FreeStablePtr@ which frees a stable pointer.
+
+%{\em Andy's comment.} {\bf Errors:} The following is not strictly true: the current
+%implementation is not as polymorphic as claimed.  The reason for this
+%is that the C programmer will have to use a different entry-routine
+%for each type of stable pointer.  At present, we only supply a very
+%limited number (3) of these routines.  It might be possible to
+%increase the range of these routines by providing general purpose
+%entry points to apply stable pointers to (stable pointers to)
+%arguments and to enter (stable pointers to) boxed primitive values.
+%{\em End of Andy's comment.}
+
+%
+% Rewritten and updated for MallocPtr++ -- 4/96 SOF
+%
+\subsubsection{Foreign objects}
+\index{Foreign objects}
+\index{ForeignObj type}
+
+A @ForeignObj#@ is a reference to an object outside the Haskell world
+(i.e., from the C world, or a reference to an object on another
+machine completely.), where the Haskell world has been told ``Let me
+know when you're finished with this ...''.
+
 \begin{verbatim}
-data PatBuffer # just a bunch of bytes (mutable)
-
-data REmatch
- = REmatch (Array Int GroupBounds)  -- for $1, ... $n
-          GroupBounds              -- for $` (everything before match)
-          GroupBounds              -- for $& (entire matched string)
-          GroupBounds              -- for $' (everything after)
-          GroupBounds              -- for $+ (matched by last bracket)
-
--- GroupBounds hold the interval where a group
--- matched inside a string, e.g.
---
--- matching "reg(exp)" "a regexp" returns the pair (5,7) for the
--- (exp) group. (PackedString indices start from 0)
-
-type GroupBounds = (Int, Int)
-
-re_compile_pattern
-       :: PackedString -- pattern to compile
-       -> Bool                 -- True <=> assume single-line mode
-       -> Bool                 -- True <=> case-insensitive
-       -> PrimIO PatBuffer
-
-re_match :: PatBuffer          -- compiled regexp
-        -> PackedString        -- string to match
-        -> Int                 -- start position
-        -> Bool                -- True <=> record results in registers
-        -> PrimIO (Maybe REmatch)
-
--- Matching on 2 strings is useful when you're dealing with multiple
--- buffers, which is something that could prove useful for
--- PackedStrings, as we don't want to stuff the contents of a file
--- into one massive heap chunk, but load (smaller chunks) on demand.
-
-re_match2 :: PatBuffer         -- 2-string version
-         -> PackedString
-         -> PackedString
-         -> Int
-         -> Int
-         -> Bool
-         -> PrimIO (Maybe REmatch)
-
-re_search :: PatBuffer         -- compiled regexp
-         -> PackedString       -- string to search
-         -> Int                -- start index
-         -> Int                -- stop index
-         -> Bool               -- True <=> record results in registers
-         -> PrimIO (Maybe REmatch)
-
-re_search2 :: PatBuffer                -- Double buffer search
-          -> PackedString
-          -> PackedString
-          -> Int               -- start index
-          -> Int               -- range (?)
-          -> Int               -- stop index
-          -> Bool              -- True <=> results in registers
-          -> PrimIO (Maybe REmatch)
+type ForeignObj#
 \end{verbatim}
 
-The \tr{MatchPS} module provides Perl-like ``higher-level'' facilities
-to operate on \tr{PackedStrings}.  The regular expressions in
-question are in Perl syntax.  The ``flags'' on various functions can
-include: \tr{i} for case-insensitive, \tr{s} for single-line mode, and
-\tr{g} for global.  (It's probably worth your time to peruse the
-source code...)
+GHC provides two primitives on @ForeignObj#@:
 
 \begin{verbatim}
-matchPS :: PackedString    -- regexp
-       -> PackedString    -- string to match
-       -> [Char]           -- flags
-       -> Maybe REmatch    -- info about what matched and where
-
-searchPS :: PackedString   -- regexp
-        -> PackedString   -- string to match
-        -> [Char]          -- flags
-        -> Maybe REmatch
-
--- Perl-like match-and-substitute:
-substPS :: PackedString    -- regexp
-       -> PackedString    -- replacement
-       -> [Char]           -- flags
-       -> PackedString    -- string
-       -> PackedString
-
--- same as substPS, but no prefix and suffix:
-replacePS :: PackedString  -- regexp
-         -> PackedString  -- replacement
-         -> [Char]         -- flags
-         -> PackedString  -- string
-         -> PackedString
-
-match2PS :: PackedString   -- regexp
-        -> PackedString   -- string1 to match
-        -> PackedString   -- string2 to match
-        -> [Char]          -- flags
-        -> Maybe REmatch
-
-search2PS :: PackedString  -- regexp
-         -> PackedString  -- string to match
-         -> PackedString  -- string to match
-         -> [Char]         -- flags
-         -> Maybe REmatch
-
--- functions to pull the matched pieces out of an REmatch:
-
-getMatchesNo    :: REmatch -> Int
-getMatchedGroup :: REmatch -> Int -> PackedString -> PackedString
-getWholeMatch   :: REmatch -> PackedString -> PackedString
-getLastMatch    :: REmatch -> PackedString -> PackedString
-getAfterMatch   :: REmatch -> PackedString -> PackedString
-
--- (reverse) brute-force string matching;
--- Perl equivalent is index/rindex:
-findPS, rfindPS :: PackedString -> PackedString -> Maybe Int
-
--- Equivalent to Perl "chop" (off the last character, if any):
-chopPS :: PackedString -> PackedString
-
--- matchPrefixPS: tries to match as much as possible of strA starting
--- from the beginning of strB (handy when matching fancy literals in
--- parsers):
-matchPrefixPS :: PackedString -> PackedString -> Int
+makeForeignObj# 
+       :: Addr# -- foreign reference
+        -> Addr# -- pointer to finalisation routine
+       -> StateAndForeignObj# RealWorld ForeignObj#
+writeForeignObj 
+       :: ForeignObj#        -- foreign object
+       -> Addr#              -- datum
+       -> State# RealWorld
+       -> State# RealWorld
 \end{verbatim}
 
-%************************************************************************
-%*                                                                      *
-\subsubsection[Socket]{Network-interface toolkit---@Socket@ and @SocketPrim@}
-\index{SocketPrim interface (GHC syslib)}
-\index{Socket interface (GHC syslib)}
-\index{network-interface library}
-\index{sockets library}
-\index{BSD sockets library}
-%*                                                                      *
-%************************************************************************
+The module @Foreign@ (Section \ref{sec:foreign-obj}) provides a more
+programmer-friendly interface to foreign objects.
 
-(Darren Moffat supplied the network-interface toolkit.)
+\subsubsection{Synchronizing variables (M-vars)}
+\index{Synchronising variables (M-vars)}
+\index{M-Vars}
 
-Your best bet for documentation is to look at the code---really!--- 
-normally in \tr{hslibs/ghc/src/{BSD,Socket,SocketPrim}.lhs}.
+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).
 
-The \tr{BSD} module provides functions to get at system-database info;
-pretty straightforward if you're into this sort of thing:
 \begin{verbatim}
-getHostName        :: IO String
-
-getServiceByName    :: ServiceName -> IO ServiceEntry
-getServicePortNumber:: ServiceName -> IO PortNumber
-getServiceEntry            :: IO ServiceEntry
-setServiceEntry            :: Bool -> IO ()
-endServiceEntry            :: IO ()
-
-getProtocolByName   :: ProtocolName -> IO ProtocolEntry
-getProtocolByNumber :: ProtocolNumber -> IO ProtcolEntry
-getProtocolNumber   :: ProtocolName -> ProtocolNumber
-getProtocolEntry    :: IO ProtocolEntry
-setProtocolEntry    :: Bool -> IO ()
-endProtocolEntry    :: IO ()
-
-getHostByName      :: HostName -> IO HostEntry
-getHostByAddr      :: Family -> HostAddress -> IO HostEntry
-getHostEntry       :: IO HostEntry
-setHostEntry       :: Bool -> IO ()
-endHostEntry       :: IO ()
+type SynchVar# s elt   -- primitive
+
+newSynchVar#:: State# s -> StateAndSynchVar# s elt
+takeMVar#   :: SynchVar# s elt -> State# s -> StateAndPtr# s elt
+putMVar#    :: SynchVar# s elt -> State# s -> State# s
 \end{verbatim}
 
-The \tr{SocketPrim} interface provides quite direct access to the
-socket facilities in a BSD Unix system, including all the
-complications.  We hope you don't need to use it!  See the source if
-needed...
+\subsubsection{@spark#@ primitive operation (for parallel execution)}
 
-The \tr{Socket} interface is a ``higher-level'' interface to sockets,
-and it is what we recommend.  Please tell us if the facilities it
-offers are inadequate to your task!
+{\em ToDo: say something}  It's used in the unfolding for @par@.
+
+\subsubsection{The @errorIO#@ primitive operation}
+
+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.
 
-The interface is relatively modest:
 \begin{verbatim}
-connectTo      :: Hostname -> PortID -> IO Handle
-listenOn       :: PortID -> IO Socket
+errorIO# :: (State# RealWorld# -> a -> a
+\end{verbatim}
 
-accept         :: Socket -> IO (Handle, HostName)
-sendTo         :: Hostname -> PortID -> String -> IO ()
+%------------------------------------------------------------
+\subsection{GHC/Hugs Extension Libraries}
 
-recvFrom       :: Hostname -> PortID -> IO String
-socketPort     :: Socket -> IO PortID
+\subsubsection{@LazyST@}
+\index{LazyST module}
 
-data PortID    -- PortID is a non-abstract type
-  = Service String     -- Service Name eg "ftp"
-  | PortNumber Int     -- User defined Port Number
-  | UnixSocket String  -- Unix family socket in file system
+This library provides support for both {\em lazy\/} and {\em strict\/}
+state threads.  In addition to the monad {\tt ST}, it also provides
+mutable variables {\tt STRef} and mutable arrays {\tt STArray}.  As
+the name suggests, the monad {\tt ST} instance is {\em lazy\/}.
 
-type Hostname = String
+\begin{verbatim}
+module LazyST( module LazyST, module Monad ) where
+import Monad
+
+data ST s a        -- abstract type
+runST              :: forall a. (forall s. ST s a) -> a
+returnST           :: a -> ST s a
+thenLazyST         :: ST s a -> (a -> ST s b) -> ST s b
+thenStrictST       :: ST s a -> (a -> ST s b) -> ST s b
+fixST              :: (a -> ST s a) -> ST s a
+unsafeInterleaveST :: ST s a -> ST s a
+instance Functor (ST s)
+instance Monad   (ST s)
+
+data STRef s a     -- mutable variables in state thread s
+                   -- containing values of type a.
+newSTRef           :: a -> ST s (STRef s a)
+readSTRef          :: STRef s a -> ST s a
+writeSTRef         :: STRef s a -> a -> ST s ()
+instance Eq (STRef s a)
+
+data STArray s ix elt -- mutable arrays in state thread s
+                      -- indexed by values of type ix
+                      -- containing values of type a.
+newSTArray          :: Ix ix => (ix,ix) -> elt -> ST s (STArray s ix elt)
+boundsSTArray       :: Ix ix => STArray s ix elt -> (ix, ix)
+readSTArray         :: Ix ix => STArray s ix elt -> ix -> ST s elt
+writeSTArray        :: Ix ix => STArray s ix elt -> ix -> elt -> ST s ()
+thawSTArray         :: Ix ix => Array ix elt -> ST s (STArray s ix elt)
+freezeSTArray       :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
+unsafeFreezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)  
+instance Eq (STArray s ix elt)
 \end{verbatim}
 
-Various examples of networking Haskell code are provided in
-\tr{ghc/misc/examples/}, notably the \tr{net???/Main.hs} programs.
 
-%************************************************************************
-%*                                                                      *
-\subsection[HBC-library]{The HBC system library}
-\index{HBC system library}
-\index{system library, HBC}
-%*                                                                      *
-%************************************************************************
+Notes:
+\begin{itemize}
+\item  
+GHC also supports ByteArrays --- these aren't supported by Hugs yet.
+\item  
+The operations {\tt freezeSTArray} and {\tt thawSTArray} convert mutable
+arrays to and from immutable arrays.  Semantically, they are identical
+to copying the array and they are usually implemented that way.  The
+operation {\tt unsafeFreezeSTArray} is a faster version of
+{\tt freezeSTArray} which omits the copying step.  It's a safe substitute for
+{\tt freezeSTArray} if you don't modify the mutable array after freezing it.
+\item In the current version of Hugs, the {\tt runST} operation,
+used to specify encapsulation, is implemented as a language construct,
+and {\tt runST} is treated as a keyword.  We plan to change this to match
+GHC soon.
 
-This documentation is stolen directly from the HBC distribution.  The
-modules that GHC does not support (because they require HBC-specific
-extensions) are omitted.
+\item The only difference between the lazy and strict instances of the
+{\tt ST} monad is in their bind operators.  The monadic bind operators
+{\tt thenLazyST} and {\tt thenStrictST} are provided so that you can
+import {\tt LazyST} (say) and still use the strict instance in those
+places where it matters.  GHC also allows you to write {\tt LazyST.>>=}
+and {\tt ST.>>=} but this is not supported by Hugs yet.
+
+\end{itemize}
+
+
+
+
+
+\subsubsection{@ST@}
+\index{ST module}
+
+
+
+This library is identical to {\tt LazyST} except that the {\tt ST} monad
+instance is {\em strict\/}.  Most programmers use the {\em strict\/} instance
+to avoid the space leaks associated with the {\em lazy\/} instance.
+
+
+
+
+\subsubsection{@IOExts@}
+\index{IOExts module}
+
+
+
+This library provides the following extensions to the IO monad:
+\begin{itemize}
+\item The operations {\tt fixIO}, {\tt unsafePerformIO} and {\tt
+unsafeInterleaveIO}.
+\item References (aka mutable variables) and mutable arrays (but no form of 
+mutable byte arrays)
+\item {\tt performGC} triggers an immediate garbage collection
+\item When called, {\tt trace} prints the string in its first argument, and then
+returns the second argument as its result.  The {\tt trace} function is not
+referentially transparent, and should only be used for debugging, or for
+monitoring execution. 
+
+\end{itemize}
+
+
+\begin{verbatim}
+module IOExts where
+
+fixIO               :: (a -> IO a) -> IO a
+unsafePerformIO     :: IO a -> a
+unsafeInterleaveIO  :: IO a -> IO a
+                    
+data IORef a        -- mutable variables containing values of type a
+newIORef            :: a -> IO (IORef a)
+readIORef           :: IORef a -> IO a
+writeIORef          :: IORef a -> a -> IO ()
+instance Eq (IORef a)
+
+data IOArray ix elt -- mutable arrays indexed by values of type ix
+                    -- containing values of type a.
+newIOArray          :: Ix ix => (ix,ix) -> elt -> IO (IOArray ix elt)
+boundsIOArray       :: Ix ix => IOArray ix elt -> (ix, ix)
+readIOArray         :: Ix ix => IOArray ix elt -> ix -> IO elt
+writeIOArray        :: Ix ix => IOArray ix elt -> ix -> elt -> IO ()
+freezeIOArray       :: Ix ix => IOArray ix elt -> IO (Array ix elt)
+instance Eq (IOArray ix elt)
+
+trace               :: String -> a -> a
+performGC           :: IO ()
+\end{verbatim}
+
+
+
+
+
+
+
+\subsubsection{@Bits@}
+\index{Bits module}
+
+
+
+This library defines bitwise operations for signed and unsigned ints.
 
-\begin{description}
-\item[\tr{ListUtil}:]
-\index{ListUtil module (HBC library)}%
-Various useful functions involving lists that are missing from the
-\tr{Prelude}:
 \begin{verbatim}
-assoc :: (Eq c) => (a -> b) -> b -> [(c, a)] -> c -> b
-        -- assoc f d l k looks for k in the association list l, if it
-        -- is found f is applied to the value, otherwise d is returned.
-concatMap :: (a -> [b]) -> [a] -> [b]
-        -- flattening map (LML's concmap)
-unfoldr :: (a -> (b, a)) -> (a -> Bool) -> a -> [b]
-        -- unfoldr f p x repeatedly applies f to x until (p x) holds.
-        -- (f x) should give a list element and a new x.
-mapAccuml :: (a -> b -> (a, c)) -> a -> [b] -> (a, [c])
-        -- mapAccuml f s l maps f over l, but also threads the state s
-        -- through (LML's mapstate).
-union :: (Eq a) => [a] -> [a] -> [a]
-        -- union of two lists
-intersection :: (Eq a) => [a] -> [a] -> [a]
-        -- intersection of two lists
-chopList :: ([a] -> (b, [a])) -> [a] -> [b]
-        -- LMLs choplist
-assocDef :: (Eq a) => [(a, b)] -> b -> a -> b
-        -- LMLs assocdef
-lookup :: (Eq a) => [(a, b)] -> a -> Option b
-        -- lookup l k looks for the key k in the association list l
-        -- and returns an optional value
-tails :: [a] -> [[a]]
-        -- return all the tails of a list
-rept :: (Integral a) => a -> b -> [b]
-        -- repeat a value a number of times
-groupEq :: (a->a->Bool) -> [a] -> [[a]]
-        -- group list elements according to an equality predicate
-group :: (Eq a) => [a] -> [[a]]
-        -- group according to} ==
-readListLazily :: (Read a) => String -> [a]
-        -- read a list in a lazy fashion
+module Bits where
+infixl 8 `shift`, `rotate`
+infixl 7 .&.
+infixl 6 `xor`
+infixl 5 .|.
+
+class Bits a where
+  (.&.), (.|.), xor :: a -> a -> a
+  complement        :: a -> a
+  shift             :: a -> Int -> a
+  rotate            :: a -> Int -> a
+  bit               :: Int -> a        
+  setBit            :: a -> Int -> a   
+  clearBit          :: a -> Int -> a   
+  complementBit     :: a -> Int -> a   
+  testBit           :: a -> Int -> Bool
+  bitSize           :: a -> Int
+  isSigned          :: a -> Bool
+
+shiftL, shiftR   :: Bits a => a -> Int -> a
+rotateL, rotateR :: Bits a => a -> Int -> a
+shiftL  a i = shift  a i
+shiftR  a i = shift  a (-i)
+rotateL a i = rotate a i
+rotateR a i = rotate a (-i)
 \end{verbatim}
 
-\item[\tr{Pretty}:]
-\index{Pretty module (HBC library)}%
-John Hughes's pretty printing library.  
+
+Notes:
+\begin{itemize}
+\item {\tt bitSize} and {\tt isSigned} are like {\tt floatRadix} and {\tt floatDigits}
+-- they return parameters of the {\em type\/} of their argument rather than 
+of the particular argument they are applied to.  {\tt bitSize} returns
+the number of bits in the type (or {\tt Nothing} for unbounded types); and
+{\tt isSigned} returns whether the type is signed or not.  
+\item {\tt shift} performs sign extension.  
+That is, right shifts fill the top bits with 1 if the  number is negative
+and with 0 otherwise.
+(Since unsigned types are always positive, the top bit is always filled with
+0.)
+\item  
+Bits are numbered from 0 with bit 0 being the least significant bit.
+\item {\tt shift x i} and {\tt rotate x i} shift to the left if {\tt i} is
+positive and to the right otherwise.  
+\item {\tt bit i} is the value with the i'th bit set.
+\end{itemize}
+
+
+
+
+
+\subsubsection{@Word@}
+\index{Word module}
+
+
+
+This library provides unsigned integers of various sizes.
+The types supported are as follows:
+
+\begin{tabular}{|l|l|}
+type &  number of bits \\ 
+\hline
+Word8 &  8 \\ 
+Word16 &  16 \\ 
+Word32 &  32 \\ 
+Word64 &  64 \\ 
+\hline
+\end{tabular}
+
+
+For each type {\it W\/} above, we provide the following functions and
+instances.  The type {\it I\/} refers to the signed integer type of the
+same size.
+
 \begin{verbatim}
-type Context = (Bool, Int, Int, Int)
-type IText = Context -> [String]
-text :: String -> IText                 -- just text
-(~.) :: IText -> IText -> IText         -- horizontal composition
-(^.) :: IText -> IText -> IText         -- vertical composition
-separate :: [IText] -> IText            -- separate by spaces
-nest :: Int -> IText -> IText           -- indent
-pretty :: Int -> Int -> IText -> String -- format it
+data W            -- Unsigned Ints
+instance Eq       W
+instance Ord      W
+instance Show     W
+instance Read     W
+instance Bounded  W
+instance Num      W
+instance Real     W
+instance Integral W
+instance Enum     W
+instance Ix       W
+instance Bits     W
 \end{verbatim}
 
-\item[\tr{QSort}:]
-\index{QSort module (HBC library)}%
-A sort function using quicksort.
+Plus
 \begin{verbatim}
-sortLe :: (a -> a -> Bool) -> [a] -> [a]
-        -- sort le l  sorts l with le as less than predicate
-sort :: (Ord a) => [a] -> [a]
-        -- sort l  sorts l using the Ord class
+word8ToWord32  :: Word8  -> Word32
+word32ToWord8  :: Word32 -> Word8
+word16ToWord32 :: Word16 -> Word32
+word32ToWord16 :: Word32 -> Word16
+
+word8ToInt     :: Word8  -> Int
+intToWord8     :: Int    -> Word8
+word16ToInt    :: Word16 -> Int
+intToWord16    :: Int    -> Word16
+word32ToInt    :: Word32 -> Int
+intToWord32    :: Int    -> Word32
 \end{verbatim}
 
-\item[\tr{Random}:]
-\index{Random module (HBC library)}%
-Random numbers.
+
+Notes: 
+\begin{itemize}
+\item All arithmetic is performed modulo 2\verb+^+n
+
+One non-obvious consequequence of this is that {\tt negate}
+should {\em not\/} raise an error on negative arguments.
+\item The coercion {\tt wToI} converts an unsigned n-bit value to the
+signed n-bit value with the same representation.  For example,
+{\tt word8ToInt8 0xff = -1}. 
+Likewise, {\tt iToW} converts signed n-bit values to the
+corresponding unsigned n-bit value.
+\item ToDo: complete the set of coercion functions.
+\item Use {\tt Prelude.fromIntegral :: (Integral a, Num b) => a -> b} to
+coerce between different sizes or to preserve sign when converting
+between values of the same size.
+\item It would be very natural to add a type a type {\tt Natural} providing
+an unbounded size unsigned integer --- just as {\tt Integer} provides
+unbounded size signed integers.  We do not do that yet since there is
+no demand for it.  Doing so would require {\tt Bits.bitSize} to return
+{\tt Maybe Int}.
+\item The {\tt Enum} instances stop when they reach their upper or lower
+bound --- they don't overflow the way the {\tt Int} and {\tt Float}
+instances do.
+\item It would be useful to provide a function (or a family of functions?)
+which coerced between any two Word types (without going through
+Integer).
+\end{itemize}
+
+
+Hugs only provides {\tt Eq}, {\tt Ord}, {\tt Read} and {\tt Show}
+instances for {\tt Word64} at the moment.
+
+
+
+
+\subsubsection{@Int@}
+\index{Int module}
+
+
+
+This library provides signed integers of various sizes.  The types
+supported are as follows:
+
+\begin{tabular}{|l|l|l|}
+type &  number of bits \\ 
+\hline
+Int8 &  8 \\ 
+Int16 &  16 \\ 
+Int32 &  32 \\ 
+Int64 &  64 \\ 
+\hline
+\end{tabular}
+
+
+For each type {\it I\/} above, we provide the following instances.
+
 \begin{verbatim}
-randomInts :: Int -> Int -> [Int]
-        -- given two seeds gives a list of random Int
-randomDoubles :: Int -> Int -> [Double]
-        -- random Double with uniform distribution in (0,1)
-normalRandomDoubles :: Int -> Int -> [Double]
-        -- random Double with normal distribution, mean 0, variance 1
+data I            -- Signed Ints
+iToInt            :: I -> Int  -- not provided for Int64
+intToi            :: Int -> I  -- not provided for Int64
+instance Eq       I
+instance Ord      I
+instance Show     I
+instance Read     I
+instance Bounded  I
+instance Num      I
+instance Real     I
+instance Integral I
+instance Enum     I
+instance Ix       I
+instance Bits     I
 \end{verbatim}
 
-\item[\tr{Trace}:]
-Simple tracing.  (Note: This comes with GHC anyway.)
+Plus
 \begin{verbatim}
-trace :: String -> a -> a       -- trace x y  prints x and returns y
+int8ToInt  :: Int8  -> Int
+intToInt8  :: Int   -> Int8
+int16ToInt :: Int16 -> Int
+intToInt16 :: Int   -> Int16
+int32ToInt :: Int32 -> Int
+intToInt32 :: Int   -> Int32
 \end{verbatim}
 
-\item[\tr{Miranda}:]
-\index{Miranda module (HBC library)}%
-Functions found in the Miranda library.
-(Note: Miranda is a registered trade mark of Research Software Ltd.)
 
-\item[\tr{Word}:]
-\index{Word module (HBC library)}
-Bit manipulation.  (GHC doesn't implement absolutely all of this.
-And don't count on @Word@ being 32 bits on a Alpha...)
+\begin{itemize}
+\item Hugs does not provide {\tt Int64} at the moment.
+\item ToDo: complete the set of coercion functions.
+\end{itemize}
+
+
+
+
+
+\subsubsection{@Addr@}
+\index{Addr module}
+
+
+
+This library provides machine addresses and is primarily intended for 
+use in creating foreign function interfaces using GreenCard.
+
 \begin{verbatim}
-class Bits a where
-    bitAnd :: a -> a -> a       -- bitwise and
-    bitOr :: a -> a -> a        -- bitwise or
-    bitXor :: a -> a -> a       -- bitwise xor
-    bitCompl :: a -> a          -- bitwise negation
-    bitRsh :: a -> Int -> a     -- bitwise right shift
-    bitLsh :: a -> Int -> a     -- bitwise left shift
-    bitSwap :: a -> a           -- swap word halves
-    bit0 :: a                   -- word with least significant bit set
-    bitSize :: a -> Int         -- number of bits in a word
-
-data Byte                       -- 8  bit quantity
-data Short                      -- 16 bit quantity
-data Word                       -- 32 bit quantity
-
-instance Bits Byte, Bits Short, Bits Word
-instance Eq Byte, Eq Short, Eq Word
-instance Ord Byte, Ord Short, Ord Word
-instance Show Byte, Show Short, Show Word
-instance Num Byte, Num Short, Num Word
-wordToShorts :: Word -> [Short]   -- convert a Word to two Short
-wordToBytes :: Word -> [Byte]     -- convert a Word to four Byte
-bytesToString :: [Byte] -> String -- convert a list of Byte to a String (bit by bit)
-wordToInt :: Word -> Int          -- convert a Word to Int
-shortToInt :: Short -> Int        -- convert a Short to Int
-byteToInt :: Byte -> Int          -- convert a Byte to Int
+module Addr where
+data Addr  -- Address type
+instance Eq Addr
+
+nullAddr           :: Addr
+plusAddr           :: Addr -> Int -> Addr
+
+-- read value out of _immutable_ memory
+indexCharOffAddr   :: Addr -> Int -> Char
+indexIntOffAddr    :: Addr -> Int -> Int     -- should we drop this?
+indexAddrOffAddr   :: Addr -> Int -> Addr
+indexFloatOffAddr  :: Addr -> Int -> Float
+indexDoubleOffAddr :: Addr -> Int -> Double
+indexWord8OffAddr  :: Addr -> Int -> Word8
+indexWord16OffAddr :: Addr -> Int -> Word16
+indexWord32OffAddr :: Addr -> Int -> Word32
+indexWord64OffAddr :: Addr -> Int -> Word64
+indexInt8OffAddr   :: Addr -> Int -> Int8
+indexInt16OffAddr  :: Addr -> Int -> Int16
+indexInt32OffAddr  :: Addr -> Int -> Int32
+indexInt64OffAddr  :: Addr -> Int -> Int64
+
+-- read value out of mutable memory
+readCharOffAddr    :: Addr -> Int -> IO Char
+readIntOffAddr     :: Addr -> Int -> IO Int  -- should we drop this?
+readAddrOffAddr    :: Addr -> Int -> IO Addr
+readFloatOffAddr   :: Addr -> Int -> IO Float
+readDoubleOffAddr  :: Addr -> Int -> IO Double
+readWord8OffAddr   :: Addr -> Int -> IO Word8
+readWord16OffAddr  :: Addr -> Int -> IO Word16
+readWord32OffAddr  :: Addr -> Int -> IO Word32
+readWord64OffAddr  :: Addr -> Int -> IO Word64
+readInt8OffAddr    :: Addr -> Int -> IO Int8
+readInt16OffAddr   :: Addr -> Int -> IO Int16
+readInt32OffAddr   :: Addr -> Int -> IO Int32
+readInt64OffAddr   :: Addr -> Int -> IO Int64
+
+-- write value into mutable memory
+writeCharOffAddr   :: Addr -> Int -> Char   -> IO ()
+writeIntOffAddr    :: Addr -> Int -> Int    -> IO ()  -- should we drop this?
+writeAddrOffAddr   :: Addr -> Int -> Addr   -> IO ()
+writeFloatOffAddr  :: Addr -> Int -> Float  -> IO ()
+writeDoubleOffAddr :: Addr -> Int -> Double -> IO ()
+writeWord8OffAddr  :: Addr -> Int -> Word8  -> IO ()
+writeWord16OffAddr :: Addr -> Int -> Word16 -> IO ()
+writeWord32OffAddr :: Addr -> Int -> Word32 -> IO ()
+writeWord64OffAddr :: Addr -> Int -> Word64 -> IO ()
+writeInt8OffAddr   :: Addr -> Int -> Int8   -> IO ()
+writeInt16OffAddr  :: Addr -> Int -> Int16  -> IO ()
+writeInt32OffAddr  :: Addr -> Int -> Int32  -> IO ()
+writeInt64OffAddr  :: Addr -> Int -> Int64  -> IO ()
 \end{verbatim}
 
-\item[\tr{Time}:]
-\index{Time module (HBC library)}%
-Manipulate time values (a Double with seconds since 1970).
+
+Hugs and GHC provide {\tt Addr} and {\tt nullAddr} but do not provide
+any of the index, read or write functions.  They can be implemented
+using GreenCard if required.
+
+
+
+
+\subsubsection{@Concurrent@}
+\index{Concurrent module}
+
+
+
+This library provides the Concurrent Haskell extensions.
+
+We are grateful to the Glasgow Haskell Project for allowing us to
+redistribute their implementation of this module.
+
+\begin{verbatim}
+module Concurrent where
+
+data ThreadId    -- thread identifiers
+instance Eq ThreadId
+
+forkIO           :: IO () -> IO ThreadId
+killThread       :: ThreadId -> IO ()
+
+data MVar a      -- Synchronisation variables
+newEmptyMVar     :: IO (MVar a)
+newMVar          :: a -> IO (MVar a)
+takeMVar         :: MVar a -> IO a
+putMVar          :: MVar a -> a -> IO ()
+swapMVar         :: MVar a -> a -> IO a
+readMVar         :: MVar a -> IO a 
+instance Eq (MVar a)
+
+data Chan a      -- channels
+newChan          :: IO (Chan a)
+writeChan        :: Chan a -> a -> IO ()
+readChan         :: Chan a -> IO a
+dupChan          :: Chan a -> IO (Chan a)
+unReadChan       :: Chan a -> a -> IO ()
+readChanContents :: Chan a -> IO [a]
+writeList2Chan   :: Chan a -> [a] -> IO ()
+                      
+data CVar a       -- one element channels
+newCVar          :: IO (CVar a)
+putCVar          :: CVar a -> a -> IO ()
+getCVar          :: CVar a -> IO a
+                      
+data QSem        -- General/quantity semaphores
+newQSem          :: Int  -> IO QSem
+waitQSem         :: QSem -> IO ()
+signalQSem       :: QSem -> IO ()
+                      
+data QSemN       -- General/quantity semaphores
+newQSemN         :: Int   -> IO QSemN
+waitQSemN        :: QSemN -> Int -> IO ()
+signalQSemN      :: QSemN -> Int -> IO ()
+
+type SampleVar a -- Sample variables 
+newEmptySampleVar:: IO (SampleVar a)
+newSampleVar     :: a -> IO (SampleVar a)
+emptySampleVar   :: SampleVar a -> IO ()
+readSampleVar    :: SampleVar a -> IO a
+writeSampleVar   :: SampleVar a -> a -> IO ()
+\end{verbatim}
+
+
+Notes:
+\begin{itemize}
+\item  
+GHC uses preemptive multitasking:
+Context switches can occur at any time, except if you call a C
+function (like \verb"getchar") that blocks waiting for input.
+
+Hugs uses cooperative multitasking:
+Context switches only occur when you use one of the primitives
+defined in this module.  This means that programs such as:
+
+\begin{verbatim}
+main = forkIO (write 'a') >> write 'b'
+ where write c = putChar c >> write c
+\end{verbatim}
+
+
+will print either {\tt aaaaaaaaaaaaaa...} or {\tt bbbbbbbbbbbb...},
+instead of some random interleaving of {\tt a}s and {\tt b}s.
+
+In practice, cooperative multitasking is sufficient for writing 
+simple graphical user interfaces.
+\item Hugs does not provide the functions {\tt mergeIO} or {\tt nmergeIO} since these
+require preemptive multitasking.
+\item {\tt killThread} has not been implemented yet on either system.
+The plan is that {\tt killThread} will raise an IO exception in the
+killed thread which it can catch --- perhaps allowing it to kill its
+children before exiting.
+\item The {\tt Ord} instance for {\tt ThreadId}s provides an arbitrary total ordering
+which might be used to build an ordered binary tree, say.  
+\end{itemize}
+
+
+
+
+
+\subsubsection{@Pretty@}
+\index{Pretty module}
+
+
+
+This library contains Simon Peyton Jones' implementation of John
+Hughes's pretty printer combinators.
+
+\begin{verbatim}
+module Pretty where
+infixl 6 <> 
+infixl 6 <+>
+infixl 5 $$, $+$
+data Doc  -- the Document datatype
+
+-- The primitive Doc values
+empty                     :: Doc
+text                      :: String   -> Doc 
+char                      :: Char     -> Doc
+int                       :: Int      -> Doc
+integer                   :: Integer  -> Doc
+float                     :: Float    -> Doc
+double                    :: Double   -> Doc
+rational                  :: Rational -> Doc
+semi, comma, colon, space, equals              :: Doc
+lparen, rparen, lbrack, rbrack, lbrace, rbrace :: Doc
+parens, brackets, braces  :: Doc -> Doc 
+quotes, doubleQuotes      :: Doc -> Doc
+
+-- Combining Doc values
+(<>)   :: Doc -> Doc -> Doc     -- Beside
+hcat   :: [Doc] -> Doc          -- List version of <>
+(<+>)  :: Doc -> Doc -> Doc     -- Beside, separated by space
+hsep   :: [Doc] -> Doc          -- List version of <+>
+($$)   :: Doc -> Doc -> Doc     -- Above; if there is no
+                                  -- overlap it "dovetails" the two
+vcat   :: [Doc] -> Doc          -- List version of $$
+cat    :: [Doc] -> Doc          -- Either hcat or vcat
+sep    :: [Doc] -> Doc          -- Either hsep or vcat
+fcat   :: [Doc] -> Doc          -- ``Paragraph fill'' version of cat
+fsep   :: [Doc] -> Doc          -- ``Paragraph fill'' version of sep
+nest   :: Int -> Doc -> Doc     -- Nested
+hang   :: Doc -> Int -> Doc -> Doc
+punctuate :: Doc -> [Doc] -> [Doc]      
+-- punctuate p [d1, ... dn] = [d1 <> p, d2 <> p, ... dn-1 <> p, dn]
+
+-- Displaying Doc values
+instance Show Doc
+render     :: Doc -> String             -- Uses default style
+renderStyle  :: Style -> Doc -> String
+data Style = Style { lineLength     :: Int,   -- In chars
+                       ribbonsPerLine :: Float, -- Ratio of ribbon length
+                                                -- to line length
+                       mode :: Mode
+               }
+data Mode = PageMode            -- Normal 
+            | ZigZagMode          -- With zig-zag cuts
+            | LeftMode            -- No indentation, infinitely long lines
+            | OneLineMode         -- All on one line
+\end{verbatim}
+
+\subsection{GHC-only Extension Libraries}
+
+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} as the
+Haskell report says, and the full user namespaces should be available
+to you.
+
+If you mess about with @import Prelude@... innocent hiding, e.g.,
+
 \begin{verbatim}
---               year mon  day  hour min  sec  dec-sec  weekday
-data Time = Time Int  Int  Int  Int  Int  Int  Double  Int
-dblToTime :: Double -> Time     -- convert a Double to a Time
-timeToDbl :: Time -> Double     -- convert a Time to a Double
-timeToString :: Time -> String  -- convert a Time to a readable String
+import Prelude hiding ( fromIntegral )
 \end{verbatim}
 
-\item[\tr{Hash}:]
-\index{Hash module (HBC library)}%
-Hashing functions.
+should work just fine.
+
+% this should work now?? -- SDM
+
+%There are some things you can do that will make GHC crash, e.g.,
+%hiding a standard class:
+%\begin{verbatim}
+%import Prelude hiding ( Eq(..) )
+%\end{verbatim}
+%
+%Don't do that.
+
+If you turn on @-fglasgow-exts@, the compiler will recognise and parse
+unboxed values properly. To get at the primitive operations described
+herein, import the relevant interfaces.
+
+\subsubsection{The @GlaExts@ interface}
+\index{GlaExts interface (GHC extensions)}
+
+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).
+
+\begin{verbatim}
+-- 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.
+\end{verbatim}
+
+\subsubsection[sec:mutable-array]{The @MutableArray@ interface}
+\index{MutableArray interface (GHC extensions)}
+
+The @MutableArray@ interface defines a general set of operations over
+mutable arrays (@MutableArray@) and mutable chunks of memory
+(@MutableByteArray@):
+
 \begin{verbatim}
-class Hashable a where
-    hash :: a -> Int                            -- hash a value, return an Int
--- instances for all Prelude types
-hashToMax :: (Hashable a) => Int -> a -> Int    -- hash into interval [0..x-1]
+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)
 \end{verbatim}
 
-\item[\tr{NameSupply}:]
-\index{NameSupply module (HBC library)}%
-Functions to generate unique names (Int).
+\subsubsection[sec:byte-array]{The @ByteArray@ interface}
+\index{ByteArray interface (GHC extensions)}
+
+@ByteArray@s are chunks of immutable Haskell heap:
+
 \begin{verbatim}
-type Name = Int
-initialNameSupply :: NameSupply
-        -- The initial name supply (may be different every
-        -- time the program is run.
-splitNameSupply :: NameSupply -> (NameSupply,NameSupply)
-        -- split the namesupply into two
-getName :: NameSupply -> Name
-        -- get the name associated with a name supply
+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
 \end{verbatim}
 
-\item[\tr{Parse}:]
-\index{Parse module (HBC library)}%
-Higher order functions to build parsers.  With a little care these
-combinators can be used to build efficient parsers with good error
-messages.
+\subsubsection{Stable pointers}
+
+Nothing exciting here, just simple boxing up.
 \begin{verbatim}
-infixr 8 +.+ , ..+ , +.. 
-infix  6 `act` , >>> , `into` , .> 
-infixr 4 ||| , ||! , |!! 
-data ParseResult a b 
-type Parser a b = a -> Int -> ParseResult a b 
-(|||) :: Parser a b -> Parser a b -> Parser a b
-        -- Alternative
-(||!) :: Parser a b -> Parser a b -> Parser a b
-        -- Alternative, but with committed choice
-(|!!) :: Parser a b -> Parser a b -> Parser a b
-        -- Alternative, but with committed choice
-(+.+) :: Parser a b -> Parser a c -> Parser a (b,c)
-        -- Sequence
-(..+) :: Parser a b -> Parser a c -> Parser a c
-        -- Sequence, throw away first part
-(+..) :: Parser a b -> Parser a c -> Parser a b
-        -- Sequence, throw away second part
-act   :: Parser a b -> (b->c) -> Parser a c
-        -- Action
-(>>>) :: Parser a (b,c) -> (b->c->d) -> Parser a d
-        -- Action on two items
-(.>) :: Parser a b -> c -> Parse a c
-        -- Action ignoring value
-into :: Parser a b -> (b -> Parser a c) -> Parser a c
-        -- Use a produced value in a parser.
-succeed b :: Parser a b
-        -- Always succeeds without consuming a token
-failP :: Parser a b
-        -- Always fails.
-many :: Parser a b -> Parser a [b]
-        -- Kleene star
-many1 :: Parser a b -> Parser a [b]
-        -- Kleene plus
-count :: Parser a b -> Int -> Parser a [b]
-        -- Parse an exact number of items
-sepBy1 :: Parser a b -> Parser a c -> Parser a [b]
-        -- Non-empty sequence of items separated by something
-sepBy :: Parser a b -> Parser a c -> Parser a [b]
-        -- Sequence of items separated by something
-lit :: (Eq a, Show a) => a -> Parser [a] a
-        -- Recognise a literal token from a list of tokens
-litp :: String -> (a->Bool) -> Parser [a] a
-        -- Recognise a token with a predicate.
-        -- The string is a description for error messages.
-testp :: String -> (a -> Bool) -> (Parser b a) -> Parser b a
-        -- Test a semantic value. 
-token :: (a -> Either String (b, a)) -> Parser a b
-        -- General token recogniser.
-parse :: Parser a b -> a -> Either ([String], a) [(b, a)]
-        -- Do a parse.  Return either error (possible tokens and rest
-        -- of tokens) or all possible parses.
-sParse :: (Show a) => (Parser [a] b) -> [a] -> Either String b
-        -- Simple parse.  Return error message or result.
+data StablePtr a = StablePtr (StablePtr# a)
+
+makeStablePointer :: a -> StablePtr a
+freeStablePointer :: StablePtr a -> IO ()
 \end{verbatim}
 
-%%%simpleLex :: String -> [String]              -- A simple (but useful) lexical analyzer
+\subsubsection{Foreign objects}
+\label{sec:foreign-obj}
+\index{Foreign objects}
+
+This module provides the @ForeignObj@ type and wrappers around the
+primitive operations on foreign objects.
 
-\item[\tr{Native}:]
-\index{Native module (HBC library)}%
-Functions to convert the primitive types \tr{Int}, \tr{Float}, and \tr{Double} to
-their native representation as a list of bytes (\tr{Char}).  If such a list
-is read/written to a file it will have the same format as when, e.g.,
-C read/writes the same kind of data.
 \begin{verbatim}
-type Bytes = [Char] -- A byte stream is just a list of characters
-
-class Native a where 
-    showBytes     :: a -> Bytes -> Bytes
-        -- prepend the representation of an item the a byte stream
-    listShowBytes :: [a] -> Bytes -> Bytes
-        -- prepend the representation of a list of items to a stream
-        -- (may be more efficient than repeating showBytes).
-    readBytes     :: Bytes -> Maybe (a, Bytes)
-        -- get an item from the stream and return the rest,
-        -- or fail if the stream is to short.
-    listReadBytes :: Int -> Bytes -> Maybe ([a], Bytes)
-        -- read n items from a stream.
-
-instance Native Int 
-instance Native Float 
-instance Native Double 
-instance (Native a, Native b) => Native (a,b)
-        -- juxtaposition of the two items
-instance (Native a, Native b, Native c) => Native (a, b, c)
-        -- juxtaposition of the three items
-instance (Native a) => Native [a]
-        -- an item count in an Int followed by the items
-
-shortIntToBytes :: Int -> Bytes -> Bytes
-        -- Convert an Int to what corresponds to a short in C.
-bytesToShortInt :: Bytes -> Maybe (Int, Bytes)
-        -- Get a short from a byte stream and convert to an Int.
-
-showB :: (Native a) => a -> Bytes       -- Simple interface to showBytes.
-readB :: (Native a) => Bytes -> a       -- Simple interface to readBytes.
+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 ()
+
 \end{verbatim}
+\index{ForeignObj type}
+\index{makeForeignObj function}
+\index{writeForeignObj function}
+
+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.
 
-\item[\tr{Number}:]
-\index{Number module (HBC library)}%
-Simple numbers that belong to all numeric classes and behave like
-a naive user would expect (except that printing is still ugly).
-(NB: GHC does not provide a magic way to use \tr{Numbers} everywhere,
-but you should be able to do it with normal \tr{import}ing and
-\tr{default}ing.)
 \begin{verbatim}
-data Number                     -- The type itself.
-instance ...                    -- All reasonable instances.
-isInteger :: Number -> Bool     -- Test if a Number is an integer.
+data Image = Image ForeignObj
+\end{verbatim}
+
+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:
+
+\begin{verbatim}
+createImage :: (Int,Int) -> IO Image
 \end{verbatim}
-\end{description}
 
-%************************************************************************
-%*                                                                      *
-\subsection[contrib-library]{The `contrib' system library}
-\index{contrib system library}
-\index{system library, contrib}
-%*                                                                      *
-%************************************************************************
-
-Just for a bit of fun, we took all the old contributed ``Haskell
-library'' code---Stephen J.~Bevan the main hero, converted it to
-Haskell~1.3 and heaved it into a \tr{contrib} system library.  It is
-mostly code for numerical methods (@SetMap@ is an exception); we have
-{\em no idea} whether it is any good or not.
-
-The modules provided are:
-@Adams_Bashforth_Approx@,
-@Adams_Predictor_Corrector_Approx@,
-@Choleski_Factorization@,
-@Crout_Reduction@,
-@Cubic_Spline@,
-@Fixed_Point_Approx@,
-@Gauss_Seidel_Iteration@,
-@Hermite_Interpolation@,
-@Horner@,
-@Jacobi_Iteration@,
-@LLDecompMethod@,
-@Least_Squares_Fit@,
-@Matrix_Ops@,
-@Neville_Iterated_Interpolation@,
-@Newton_Cotes@,
-@Newton_Interpolatory_Divided_Difference@,
-@Newton_Raphson_Approx@,
-@Runge_Kutta_Approx@,
-@SOR_Iteration@,
-@Secant_Approx@,
-@SetMap@,
-@Steffensen_Approx@,
-@Taylor_Approx@, and
-@Vector_Ops@.
+So far, this looks just like an @Addr@ type, but @ForeignObj@ offers a
+bit more, namely that we can specify a {\em finalisation routine} 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.
+
+\subsubsection{The @CCall@ module}
+
+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{glasgow-ccalls}.
+
+\begin{onlystandalone}
+\end{document}
+\end{onlystandalone}
+