[project @ 1997-11-24 17:42:05 by simonm]
authorsimonm <unknown>
Mon, 24 Nov 1997 17:42:05 +0000 (17:42 +0000)
committersimonm <unknown>
Mon, 24 Nov 1997 17:42:05 +0000 (17:42 +0000)
GHC/Hugs Library document.

This currently won't build until we get the right SGML tools in the tree.

ghc/docs/libraries/libs.sgml [new file with mode: 0644]

diff --git a/ghc/docs/libraries/libs.sgml b/ghc/docs/libraries/libs.sgml
new file mode 100644 (file)
index 0000000..f791cae
--- /dev/null
@@ -0,0 +1,636 @@
+<!doctype linuxdoc system>\r
+\r
+<!-- ToDo:\r
+  o Add indexing support (to linuxdoc)\r
+  o Fix citations in html\r
+  -->\r
+\r
+<article>\r
+\r
+<title>The Hugs-GHC Extension Libraries\r
+<author>Alastair Reid <tt/reid-alastair@cs.yale.edu/\r
+<date>v0.6, 17 November 1997\r
+<abstract>\r
+Hugs and GHC provide a common set of libraries to aid portability.\r
+This document specifies the interfaces to these libraries and documents\r
+known differences.  We hope that these modules will be adopted for inclusion\r
+as Standard Haskell Libraries sometime soon.\r
+</abstract>\r
+\r
+<!--  Commented out the table of contents - ADR\r
+<toc>\r
+-->\r
+\r
+<sect> <idx/LazyST/ <p>\r
+\r
+This library provides support for both <em/lazy/ and <em/strict/ state\r
+threads, as described in the PLDI '94 paper by John Launchbury and\r
+Simon Peyton Jones <cite id="LazyStateThreads">.  In addition to the\r
+monad <tt/ST/, it also provides mutable variables <tt/STRef/ and\r
+mutable arrays <tt/STArray/.  As the name suggests, the monad <tt/ST/\r
+instance is <em/lazy/.\r
+\r
+<tscreen><verb>\r
+module LazyST( module LazyST, module Monad ) where\r
+import Monad\r
+\r
+data ST s a        -- abstract type\r
+runST              :: forall a. (forall s. ST s a) -> a\r
+returnST           :: a -> ST s a\r
+thenLazyST         :: ST s a -> (a -> ST s b) -> ST s b\r
+thenStrictST       :: ST s a -> (a -> ST s b) -> ST s b\r
+fixST              :: (a -> ST s a) -> ST s a\r
+unsafeInterleaveST :: ST s a -> ST s a\r
+instance Functor (ST s)\r
+instance Monad   (ST s)\r
+\r
+data STRef s a     -- mutable variables in state thread s\r
+                   -- containing values of type a.\r
+newSTRef           :: a -> ST s (STRef s a)\r
+readSTRef          :: STRef s a -> ST s a\r
+writeSTRef         :: STRef s a -> a -> ST s ()\r
+instance Eq (STRef s a)\r
+\r
+data STArray s ix elt -- mutable arrays in state thread s\r
+                      -- indexed by values of type ix\r
+                      -- containing values of type a.\r
+newSTArray          :: Ix ix => (ix,ix) -> elt -> ST s (STArray s ix elt)\r
+boundsSTArray       :: Ix ix => STArray s ix elt -> (ix, ix)\r
+readSTArray         :: Ix ix => STArray s ix elt -> ix -> ST s elt\r
+writeSTArray        :: Ix ix => STArray s ix elt -> ix -> elt -> ST s ()\r
+thawSTArray         :: Ix ix => Array ix elt -> ST s (STArray s ix elt)\r
+freezeSTArray       :: Ix ix => STArray s ix elt -> ST s (Array ix elt)\r
+unsafeFreezeSTArray :: Ix ix => STArray s ix elt -> ST s (Array ix elt)  \r
+instance Eq (STArray s ix elt)\r
+</verb></tscreen>\r
+\r
+Notes:\r
+<itemize>\r
+\r
+<item> \r
+GHC also supports ByteArrays --- these aren't supported by Hugs yet.\r
+\r
+<item> \r
+The operations <tt/freezeSTArray/ and <tt/thawSTArray/ convert mutable\r
+arrays to and from immutable arrays.  Semantically, they are identical\r
+to copying the array and they are usually implemented that way.  The\r
+operation <tt/unsafeFreezeSTArray/ is a faster version of\r
+<tt/freezeSTArray/ which omits the copying step.  It's a safe substitute for\r
+<tt/freezeSTArray/ if you don't modify the mutable array after freezing it.\r
+\r
+<item>\r
+In the current version of Hugs, the <tt/<idx/runST// operation,\r
+used to specify encapsulation, is implemented as a language construct,\r
+and <tt/runST/ is treated as a keyword.  We plan to change this to match\r
+GHC soon.\r
+\r
+<!-- \r
+  <item>\r
+     Note that it is possible to install Hugs 1.4 without support for lazy\r
+     state threads, and hence the primitives described here may not be\r
+     available in all implementations.  Also, in contrast with the\r
+     implementation of lazy state threads in previous releases of Hugs and\r
+     Gofer, there is no direct relationship between the\r
+     <tt/<idx/ST monad// and the <tt/<idx/IO monad//.\r
+  -->\r
+\r
+<item>\r
+The only difference between the lazy and strict instances of the\r
+<tt/ST/ monad is in their bind operators.  The monadic bind operators\r
+<tt/thenLazyST/ and <tt/thenStrictST/ are provided so that you can\r
+import <tt/LazyST/ (say) and still use the strict instance in those\r
+places where it matters.  GHC also allows you to write <tt/LazyST.>>=/\r
+and <tt/ST.>>=/ but this is not supported by Hugs yet.\r
+\r
+\r
+</itemize>\r
+\r
+<sect> <idx/ST/ <p>\r
+\r
+This library is identical to <tt/LazyST/ except that the <tt/ST/ monad\r
+instance is <em/strict/.  Most programmers use the <em/strict/ instance\r
+to avoid the space leaks associated with the <em/lazy/ instance.\r
+\r
+<sect> <idx/IOExts/ <p>\r
+\r
+This library provides the following extensions to the IO monad:\r
+<itemize>\r
+<item>\r
+The operations <tt/fixIO/, <tt/unsafePerformIO/ and <tt/unsafeInterleaveIO/\r
+described in <cite id="ImperativeFP">\r
+\r
+<item>\r
+References (aka mutable variables) and mutable arrays (but no form of \r
+mutable byte arrays)\r
+\r
+<item>\r
+<tt/performGC/ triggers an immediate garbage collection\r
+\r
+<item>\r
+When called, <tt/trace/ prints the string in its first argument, and then\r
+returns the second argument as its result.  The <tt/trace/ function is not\r
+referentially transparent, and should only be used for debugging, or for\r
+monitoring execution. \r
+\r
+<!--\r
+  You should also be warned that, unless you understand some of the\r
+  details about the way that Haskell programs are executed, results\r
+  obtained using <tt/trace/ can be rather confusing.  For example, the\r
+  messages may not appear in the order that you expect.  Even ignoring the\r
+  output that they produce, adding calls to <tt/trace/ can change the\r
+  semantics of your program.  Consider this a warning!\r
+  -->\r
+\r
+</itemize>\r
+\r
+<tscreen><verb>\r
+module IOExts where\r
+\r
+fixIO               :: (a -> IO a) -> IO a\r
+unsafePerformIO     :: IO a -> a\r
+unsafeInterleaveIO  :: IO a -> IO a\r
+                   \r
+data IORef a        -- mutable variables containing values of type a\r
+newIORef           :: a -> IO (IORef a)\r
+readIORef          :: IORef a -> IO a\r
+writeIORef         :: IORef a -> a -> IO ()\r
+instance Eq (IORef a)\r
+\r
+data IOArray ix elt -- mutable arrays indexed by values of type ix\r
+                    -- containing values of type a.\r
+newIOArray          :: Ix ix => (ix,ix) -> elt -> IO (IOArray ix elt)\r
+boundsIOArray       :: Ix ix => IOArray ix elt -> (ix, ix)\r
+readIOArray         :: Ix ix => IOArray ix elt -> ix -> IO elt\r
+writeIOArray        :: Ix ix => IOArray ix elt -> ix -> elt -> IO ()\r
+freezeIOArray       :: Ix ix => IOArray ix elt -> IO (Array ix elt)\r
+instance Eq (IOArray ix elt)\r
+\r
+trace               :: String -> a -> a\r
+performGC           :: IO ()\r
+</verb></tscreen>\r
+\r
+<!--\r
+  <sect> <idx/GlaExts/ <p>\r
+  \r
+  This library provides a convenient bundle of most of the extensions\r
+  available in GHC and Hugs.  This module is generally more stable than\r
+  the other modules of non-standard extensions so you might choose to \r
+  import them from here rather than going straight to the horses mouth.\r
+  \r
+  <tscreen><verb>\r
+  module GlaExts( module GlaExts, module IOExts, module ST, module Addr ) where\r
+  import IOExts\r
+  import ST\r
+  import Addr\r
+  trace              :: String -> a -> a\r
+  performGC          :: IO ()\r
+  </verb></tscreen>\r
+  \r
+  The GHC version also provides the types <tt/PrimIO/, <tt/RealWorld/,\r
+  <tt/ByteArray/, <tt/Lift/ and operations on these types. It also\r
+  provides the unboxed views of the types\r
+  <tt/Int/, \r
+  <tt/Addr/, \r
+  <tt/Word/, \r
+  <tt/Float/, \r
+  <tt/Double/, \r
+  <tt/Integer/ and\r
+  <tt/Char/ \r
+  and a number of ``primitive operations'' (<tt/+&num/,\r
+  <tt/plusFloat&num/, etc.).\r
+  \r
+  -->\r
+\r
+<sect> <idx/Bits/ <p>\r
+\r
+This library defines bitwise operations for signed and unsigned ints.\r
+\r
+<tscreen><verb>\r
+module Bits where\r
+infixl 8 `shift`, `rotate`\r
+infixl 7 .&.\r
+infixl 6 `xor`\r
+infixl 5 .|.\r
+\r
+class Bits a where\r
+  (.&.), (.|.), xor :: a -> a -> a\r
+  complement        :: a -> a\r
+  shift             :: a -> Int -> a\r
+  rotate            :: a -> Int -> a\r
+  bit               :: Int -> a        \r
+  setBit            :: a -> Int -> a   \r
+  clearBit          :: a -> Int -> a   \r
+  complementBit     :: a -> Int -> a   \r
+  testBit           :: a -> Int -> Bool\r
+  bitSize           :: a -> Int\r
+  isSigned          :: a -> Bool\r
+\r
+shiftL, shiftR   :: Bits a => a -> Int -> a\r
+rotateL, rotateR :: Bits a => a -> Int -> a\r
+shiftL  a i = shift  a i\r
+shiftR  a i = shift  a (-i)\r
+rotateL a i = rotate a i\r
+rotateR a i = rotate a (-i)\r
+</verb></tscreen>\r
+\r
+Notes:\r
+<itemize>\r
+<item>\r
+  <tt/bitSize/ and <tt/isSigned/ are like <tt/floatRadix/ and <tt/floatDigits/\r
+  -- they return parameters of the <em/type/ of their argument rather than \r
+  of the particular argument they are applied to.  <tt/bitSize/ returns\r
+  the number of bits in the type (or <tt/Nothing/ for unbounded types); and\r
+  <tt/isSigned/ returns whether the type is signed or not.  \r
+<item>\r
+  <tt/shift/ performs sign extension.  \r
+  That is, right shifts fill the top bits with 1 if the  number is negative\r
+  and with 0 otherwise.\r
+  (Since unsigned types are always positive, the top bit is always filled with\r
+  0.)\r
+<item> \r
+  Bits are numbered from 0 with bit 0 being the least significant bit.\r
+<item>\r
+  <tt/shift x i/ and <tt/rotate x i/ shift to the left if <tt/i/ is\r
+  positive and to the right otherwise.  \r
+<!--\r
+  <item>\r
+    <tt/rotate/ is well defined only if bitSize returns a number.\r
+    (Maybe we should impose a Bounded constraint on it?)\r
+  -->\r
+<item>\r
+  <tt/bit i/ is the value with the i'th bit set.\r
+</itemize>\r
+\r
+<sect> <idx/Word/ <p>\r
+\r
+This library provides unsigned integers of various sizes.\r
+The types supported are as follows:\r
+\r
+<tabular ca="|l|l|">\r
+type    | number of bits @ \r
+<hline> \r
+Word8    | 8  @\r
+Word16   | 16 @\r
+Word32   | 32 @\r
+Word64   | 64 @\r
+<hline> \r
+</tabular>\r
+\r
+For each type <it/W/ above, we provide the following functions and\r
+instances.  The type <it/I/ refers to the signed integer type of the\r
+same size.\r
+\r
+<tscreen><verb>\r
+data W            -- Unsigned Ints\r
+instance Eq       W\r
+instance Ord      W\r
+instance Show     W\r
+instance Read     W\r
+instance Bounded  W\r
+instance Num      W\r
+instance Real     W\r
+instance Integral W\r
+instance Enum     W\r
+instance Ix       W\r
+instance Bits     W\r
+</verb></tscreen>\r
+Plus\r
+<tscreen><verb>\r
+word8ToWord32  :: Word8  -> Word32\r
+word32ToWord8  :: Word32 -> Word8\r
+word16ToWord32 :: Word16 -> Word32\r
+word32ToWord16 :: Word32 -> Word16\r
+\r
+word8ToInt     :: Word8  -> Int\r
+intToWord8     :: Int    -> Word8\r
+word16ToInt    :: Word16 -> Int\r
+intToWord16    :: Int    -> Word16\r
+word32ToInt    :: Word32 -> Int\r
+intToWord32    :: Int    -> Word32\r
+</verb></tscreen>\r
+\r
+Notes: \r
+<itemize>\r
+<item>\r
+  All arithmetic is performed modulo 2^n\r
+\r
+  One non-obvious consequequence of this is that <tt/negate/\r
+  should <em/not/ raise an error on negative arguments.\r
+\r
+<item>\r
+The coercion <tt/wToI/ converts an unsigned n-bit value to the\r
+signed n-bit value with the same representation.  For example,\r
+<tt/word8ToInt8 0xff = -1/. \r
+Likewise, <tt/iToW/ converts signed n-bit values to the\r
+corresponding unsigned n-bit value.\r
+\r
+<item>\r
+ToDo: complete the set of coercion functions.\r
+\r
+<item>\r
+Use <tt/Prelude.fromIntegral :: (Integral a, Num b) => a -> b/ to\r
+coerce between different sizes or to preserve sign when converting\r
+between values of the same size.\r
+\r
+<item>\r
+It would be very natural to add a type a type <tt/Natural/ providing\r
+an unbounded size unsigned integer --- just as <tt/Integer/ provides\r
+unbounded size signed integers.  We do not do that yet since there is\r
+no demand for it.  Doing so would require <tt/Bits.bitSize/ to return\r
+<tt/Maybe Int/.\r
+\r
+<item>\r
+The <tt/Enum/ instances stop when they reach their upper or lower\r
+bound --- they don't overflow the way the <tt/Int/ and <tt/Float/\r
+instances do.\r
+\r
+<item>\r
+It would be useful to provide a function (or a family of functions?)\r
+which coerced between any two Word types (without going through\r
+Integer).\r
+\r
+</itemize>\r
+\r
+Hugs only provides <tt/Eq/, <tt/Ord/, <tt/Read/ and <tt/Show/\r
+instances for <tt/Word64/ at the moment.\r
+\r
+<sect> <idx/Int/ <p>\r
+\r
+This library provides signed integers of various sizes.  The types\r
+supported are as follows:\r
+\r
+<tabular ca="|l|l|l|">\r
+type    | number of bits @ \r
+<hline> \r
+Int8    | 8  @\r
+Int16   | 16 @\r
+Int32   | 32 @\r
+Int64   | 64 @\r
+<hline> \r
+</tabular>\r
+\r
+For each type <it/I/ above, we provide the following instances.\r
+\r
+<tscreen><verb>\r
+data I            -- Signed Ints\r
+iToInt            :: I -> Int  -- not provided for Int64\r
+intToi            :: Int -> I  -- not provided for Int64\r
+instance Eq       I\r
+instance Ord      I\r
+instance Show     I\r
+instance Read     I\r
+instance Bounded  I\r
+instance Num      I\r
+instance Real     I\r
+instance Integral I\r
+instance Enum     I\r
+instance Ix       I\r
+instance Bits     I\r
+</verb></tscreen>\r
+Plus\r
+<tscreen><verb>\r
+int8ToInt  :: Int8  -> Int\r
+intToInt8  :: Int   -> Int8\r
+int16ToInt :: Int16 -> Int\r
+intToInt16 :: Int   -> Int16\r
+int32ToInt :: Int32 -> Int\r
+intToInt32 :: Int   -> Int32\r
+</verb></tscreen>\r
+\r
+<itemize>\r
+<item>\r
+Hugs does not provide <tt/Int64/ at the moment.\r
+\r
+<item>\r
+ToDo: complete the set of coercion functions.\r
+\r
+</itemize>\r
+\r
+<sect> <idx/Addr/ <p>\r
+\r
+This library provides machine addresses and is primarily intended for \r
+use in creating foreign function interfaces using GreenCard.\r
+\r
+<tscreen><verb>\r
+module Addr where\r
+data Addr  -- Address type\r
+instance Eq Addr\r
+\r
+nullAddr           :: Addr\r
+plusAddr           :: Addr -> Int -> Addr\r
+\r
+-- read value out of _immutable_ memory\r
+indexCharOffAddr   :: Addr -> Int -> Char\r
+indexIntOffAddr    :: Addr -> Int -> Int     -- should we drop this?\r
+indexAddrOffAddr   :: Addr -> Int -> Addr\r
+indexFloatOffAddr  :: Addr -> Int -> Float\r
+indexDoubleOffAddr :: Addr -> Int -> Double\r
+indexWord8OffAddr  :: Addr -> Int -> Word8\r
+indexWord16OffAddr :: Addr -> Int -> Word16\r
+indexWord32OffAddr :: Addr -> Int -> Word32\r
+indexWord64OffAddr :: Addr -> Int -> Word64\r
+indexInt8OffAddr   :: Addr -> Int -> Int8\r
+indexInt16OffAddr  :: Addr -> Int -> Int16\r
+indexInt32OffAddr  :: Addr -> Int -> Int32\r
+indexInt64OffAddr  :: Addr -> Int -> Int64\r
+\r
+-- read value out of mutable memory\r
+readCharOffAddr    :: Addr -> Int -> IO Char\r
+readIntOffAddr     :: Addr -> Int -> IO Int  -- should we drop this?\r
+readAddrOffAddr    :: Addr -> Int -> IO Addr\r
+readFloatOffAddr   :: Addr -> Int -> IO Float\r
+readDoubleOffAddr  :: Addr -> Int -> IO Double\r
+readWord8OffAddr   :: Addr -> Int -> IO Word8\r
+readWord16OffAddr  :: Addr -> Int -> IO Word16\r
+readWord32OffAddr  :: Addr -> Int -> IO Word32\r
+readWord64OffAddr  :: Addr -> Int -> IO Word64\r
+readInt8OffAddr    :: Addr -> Int -> IO Int8\r
+readInt16OffAddr   :: Addr -> Int -> IO Int16\r
+readInt32OffAddr   :: Addr -> Int -> IO Int32\r
+readInt64OffAddr   :: Addr -> Int -> IO Int64\r
+\r
+-- write value into mutable memory\r
+writeCharOffAddr   :: Addr -> Int -> Char   -> IO ()\r
+writeIntOffAddr    :: Addr -> Int -> Int    -> IO ()  -- should we drop this?\r
+writeAddrOffAddr   :: Addr -> Int -> Addr   -> IO ()\r
+writeFloatOffAddr  :: Addr -> Int -> Float  -> IO ()\r
+writeDoubleOffAddr :: Addr -> Int -> Double -> IO ()\r
+writeWord8OffAddr  :: Addr -> Int -> Word8  -> IO ()\r
+writeWord16OffAddr :: Addr -> Int -> Word16 -> IO ()\r
+writeWord32OffAddr :: Addr -> Int -> Word32 -> IO ()\r
+writeWord64OffAddr :: Addr -> Int -> Word64 -> IO ()\r
+writeInt8OffAddr   :: Addr -> Int -> Int8   -> IO ()\r
+writeInt16OffAddr  :: Addr -> Int -> Int16  -> IO ()\r
+writeInt32OffAddr  :: Addr -> Int -> Int32  -> IO ()\r
+writeInt64OffAddr  :: Addr -> Int -> Int64  -> IO ()\r
+</verb></tscreen>\r
+\r
+Hugs provides <tt/Addr/ and <tt/nullAddr/ but does not provide any of\r
+the index, read or write functions.  They can be implemented using \r
+GreenCard if required.\r
+\r
+<sect> <idx/ForeignObj/ <p>\r
+\r
+This module is provided by GHC but not by Hugs.\r
+GreenCard for Hugs provides the <tt/ForeignObj/ type.\r
+\r
+<sect> <idx/Concurrent/ <p>\r
+\r
+This library provides the Concurrent Haskell extensions\r
+<cite id="concurrentHaskell:popl96">.\r
+\r
+We are grateful to the Glasgow Haskell Project for allowing us to\r
+redistribute their implementation of this module.\r
+\r
+<tscreen><verb>\r
+module Concurrent where\r
+\r
+data ThreadId    -- thread identifiers\r
+instance Eq ThreadId\r
+\r
+forkIO           :: IO () -> IO ThreadId\r
+killThread       :: ThreadId -> IO ()\r
+\r
+data MVar a      -- Synchronisation variables\r
+newEmptyMVar     :: IO (MVar a)\r
+newMVar          :: a -> IO (MVar a)\r
+takeMVar         :: MVar a -> IO a\r
+putMVar          :: MVar a -> a -> IO ()\r
+swapMVar         :: MVar a -> a -> IO a\r
+readMVar         :: MVar a -> IO a \r
+instance Eq (MVar a)\r
+\r
+data Chan a      -- channels\r
+newChan          :: IO (Chan a)\r
+writeChan        :: Chan a -> a -> IO ()\r
+readChan         :: Chan a -> IO a\r
+dupChan          :: Chan a -> IO (Chan a)\r
+unReadChan       :: Chan a -> a -> IO ()\r
+readChanContents :: Chan a -> IO [a]\r
+writeList2Chan   :: Chan a -> [a] -> IO ()\r
+                      \r
+data CVar a       -- one element channels\r
+newCVar          :: IO (CVar a)\r
+putCVar          :: CVar a -> a -> IO ()\r
+getCVar          :: CVar a -> IO a\r
+                      \r
+data QSem        -- General/quantity semaphores\r
+newQSem          :: Int  -> IO QSem\r
+waitQSem         :: QSem -> IO ()\r
+signalQSem       :: QSem -> IO ()\r
+                      \r
+data QSemN       -- General/quantity semaphores\r
+newQSemN         :: Int   -> IO QSemN\r
+waitQSemN        :: QSemN -> Int -> IO ()\r
+signalQSemN      :: QSemN -> Int -> IO ()\r
+\r
+type SampleVar a -- Sample variables \r
+newEmptySampleVar:: IO (SampleVar a)\r
+newSampleVar     :: a -> IO (SampleVar a)\r
+emptySampleVar   :: SampleVar a -> IO ()\r
+readSampleVar    :: SampleVar a -> IO a\r
+writeSampleVar   :: SampleVar a -> a -> IO ()\r
+</verb></tscreen>\r
+\r
+Notes:\r
+<itemize>\r
+\r
+<item> \r
+  GHC uses preemptive multitasking:\r
+  Context switches can occur at any time, except if you call a C\r
+  function (like \verb"getchar") that blocks waiting for input.\r
+\r
+  Hugs uses cooperative multitasking:\r
+  Context switches only occur when you use one of the primitives\r
+  defined in this module.  This means that programs such as:\r
+\r
+<tscreen><verb>\r
+main = forkIO (write 'a') >> write 'b'\r
+ where write c = putChar c >> write c\r
+</verb></tscreen>\r
+\r
+  will print either <tt/aaaaaaaaaaaaaa.../ or <tt/bbbbbbbbbbbb.../,\r
+  instead of some random interleaving of <tt/a/s and <tt/b/s.\r
+\r
+  In practice, cooperative multitasking is sufficient for writing \r
+  simple graphical user interfaces.\r
+\r
+<item>\r
+Hugs does not provide the functions <tt/mergeIO/ or <tt/nmergeIO/ since these\r
+require preemptive multitasking.\r
+\r
+<item>\r
+<tt/killThread/ has not been implemented yet on either system.\r
+The plan is that <tt/killThread/ will raise an IO exception in the\r
+killed thread which it can catch --- perhaps allowing it to kill its\r
+children before exiting.\r
+\r
+<item>\r
+The <tt/Ord/ instance for <tt/ThreadId/s provides an arbitrary total ordering\r
+which might be used to build an ordered binary tree, say.  \r
+\r
+</itemize>\r
+\r
+<sect> <idx/Pretty/ <p>\r
+\r
+This library contains Simon Peyton Jones' implementation of John\r
+Hughes's pretty printer combinators.\r
+\r
+<tscreen><verb>\r
+module Pretty where\r
+infixl 6 <> \r
+infixl 6 <+>\r
+infixl 5 $$, $+$\r
+data Doc  -- the Document datatype\r
+\r
+-- The primitive Doc values\r
+empty                     :: Doc\r
+text                      :: String   -> Doc \r
+char                      :: Char     -> Doc\r
+int                       :: Int      -> Doc\r
+integer                   :: Integer  -> Doc\r
+float                     :: Float    -> Doc\r
+double                    :: Double   -> Doc\r
+rational                  :: Rational -> Doc\r
+semi, comma, colon, space, equals              :: Doc\r
+lparen, rparen, lbrack, rbrack, lbrace, rbrace :: Doc\r
+parens, brackets, braces  :: Doc -> Doc \r
+quotes, doubleQuotes      :: Doc -> Doc\r
+\r
+-- Combining Doc values\r
+(<>)   :: Doc -> Doc -> Doc     -- Beside\r
+hcat   :: [Doc] -> Doc          -- List version of <>\r
+(<+>)  :: Doc -> Doc -> Doc     -- Beside, separated by space\r
+hsep   :: [Doc] -> Doc          -- List version of <+>\r
+($$)   :: Doc -> Doc -> Doc     -- Above; if there is no\r
+                                  -- overlap it "dovetails" the two\r
+vcat   :: [Doc] -> Doc          -- List version of $$\r
+cat    :: [Doc] -> Doc          -- Either hcat or vcat\r
+sep    :: [Doc] -> Doc          -- Either hsep or vcat\r
+fcat   :: [Doc] -> Doc          -- ``Paragraph fill'' version of cat\r
+fsep   :: [Doc] -> Doc          -- ``Paragraph fill'' version of sep\r
+nest   :: Int -> Doc -> Doc     -- Nested\r
+hang   :: Doc -> Int -> Doc -> Doc\r
+punctuate :: Doc -> [Doc] -> [Doc]      \r
+-- punctuate p [d1, ... dn] = [d1 <> p, d2 <> p, ... dn-1 <> p, dn]\r
+\r
+-- Displaying Doc values\r
+instance Show Doc\r
+render     :: Doc -> String             -- Uses default style\r
+renderStyle  :: Style -> Doc -> String\r
+data Style = Style { lineLength     :: Int,   -- In chars\r
+                       ribbonsPerLine :: Float, -- Ratio of ribbon length\r
+                                                -- to line length\r
+                       mode :: Mode\r
+               }\r
+data Mode = PageMode            -- Normal \r
+            | ZigZagMode          -- With zig-zag cuts\r
+            | LeftMode            -- No indentation, infinitely long lines\r
+            | OneLineMode         -- All on one line\r
+</verb></tscreen>\r
+\r
+<biblio files="refs" style="abbrv">\r
+\r
+\r
+</article>\r
+\r