Skip to content
Snippets Groups Projects
Commit ab4374e2 authored by Simon Marlow's avatar Simon Marlow
Browse files

[project @ 1997-11-24 17:42:05 by simonm]

GHC/Hugs Library document.

This currently won't build until we get the right SGML tools in the tree.
parent b9d01c5e
No related merge requests found
<!doctype linuxdoc system>
<!-- ToDo:
o Add indexing support (to linuxdoc)
o Fix citations in html
-->
<article>
<title>The Hugs-GHC Extension Libraries
<author>Alastair Reid <tt/reid-alastair@cs.yale.edu/
<date>v0.6, 17 November 1997
<abstract>
Hugs and GHC provide a common set of libraries to aid portability.
This document specifies the interfaces to these libraries and documents
known differences. We hope that these modules will be adopted for inclusion
as Standard Haskell Libraries sometime soon.
</abstract>
<!-- Commented out the table of contents - ADR
<toc>
-->
<sect> <idx/LazyST/ <p>
This library provides support for both <em/lazy/ and <em/strict/ state
threads, as described in the PLDI '94 paper by John Launchbury and
Simon Peyton Jones <cite id="LazyStateThreads">. 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/.
<tscreen><verb>
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)
</verb></tscreen>
Notes:
<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/<idx/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.
<!--
<item>
Note that it is possible to install Hugs 1.4 without support for lazy
state threads, and hence the primitives described here may not be
available in all implementations. Also, in contrast with the
implementation of lazy state threads in previous releases of Hugs and
Gofer, there is no direct relationship between the
<tt/<idx/ST monad// and the <tt/<idx/IO monad//.
-->
<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.
</itemize>
<sect> <idx/ST/ <p>
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.
<sect> <idx/IOExts/ <p>
This library provides the following extensions to the IO monad:
<itemize>
<item>
The operations <tt/fixIO/, <tt/unsafePerformIO/ and <tt/unsafeInterleaveIO/
described in <cite id="ImperativeFP">
<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.
<!--
You should also be warned that, unless you understand some of the
details about the way that Haskell programs are executed, results
obtained using <tt/trace/ can be rather confusing. For example, the
messages may not appear in the order that you expect. Even ignoring the
output that they produce, adding calls to <tt/trace/ can change the
semantics of your program. Consider this a warning!
-->
</itemize>
<tscreen><verb>
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 ()
</verb></tscreen>
<!--
<sect> <idx/GlaExts/ <p>
This library provides a convenient bundle of most of the extensions
available in GHC and Hugs. This module is generally more stable than
the other modules of non-standard extensions so you might choose to
import them from here rather than going straight to the horses mouth.
<tscreen><verb>
module GlaExts( module GlaExts, module IOExts, module ST, module Addr ) where
import IOExts
import ST
import Addr
trace :: String -> a -> a
performGC :: IO ()
</verb></tscreen>
The GHC version also provides the types <tt/PrimIO/, <tt/RealWorld/,
<tt/ByteArray/, <tt/Lift/ and operations on these types. It also
provides the unboxed views of the types
<tt/Int/,
<tt/Addr/,
<tt/Word/,
<tt/Float/,
<tt/Double/,
<tt/Integer/ and
<tt/Char/
and a number of ``primitive operations'' (<tt/+&num/,
<tt/plusFloat&num/, etc.).
-->
<sect> <idx/Bits/ <p>
This library defines bitwise operations for signed and unsigned ints.
<tscreen><verb>
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)
</verb></tscreen>
Notes:
<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/rotate/ is well defined only if bitSize returns a number.
(Maybe we should impose a Bounded constraint on it?)
-->
<item>
<tt/bit i/ is the value with the i'th bit set.
</itemize>
<sect> <idx/Word/ <p>
This library provides unsigned integers of various sizes.
The types supported are as follows:
<tabular ca="|l|l|">
type | number of bits @
<hline>
Word8 | 8 @
Word16 | 16 @
Word32 | 32 @
Word64 | 64 @
<hline>
</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.
<tscreen><verb>
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
</verb></tscreen>
Plus
<tscreen><verb>
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
</verb></tscreen>
Notes:
<itemize>
<item>
All arithmetic is performed modulo 2^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).
</itemize>
Hugs only provides <tt/Eq/, <tt/Ord/, <tt/Read/ and <tt/Show/
instances for <tt/Word64/ at the moment.
<sect> <idx/Int/ <p>
This library provides signed integers of various sizes. The types
supported are as follows:
<tabular ca="|l|l|l|">
type | number of bits @
<hline>
Int8 | 8 @
Int16 | 16 @
Int32 | 32 @
Int64 | 64 @
<hline>
</tabular>
For each type <it/I/ above, we provide the following instances.
<tscreen><verb>
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
</verb></tscreen>
Plus
<tscreen><verb>
int8ToInt :: Int8 -> Int
intToInt8 :: Int -> Int8
int16ToInt :: Int16 -> Int
intToInt16 :: Int -> Int16
int32ToInt :: Int32 -> Int
intToInt32 :: Int -> Int32
</verb></tscreen>
<itemize>
<item>
Hugs does not provide <tt/Int64/ at the moment.
<item>
ToDo: complete the set of coercion functions.
</itemize>
<sect> <idx/Addr/ <p>
This library provides machine addresses and is primarily intended for
use in creating foreign function interfaces using GreenCard.
<tscreen><verb>
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 ()
</verb></tscreen>
Hugs provides <tt/Addr/ and <tt/nullAddr/ but does not provide any of
the index, read or write functions. They can be implemented using
GreenCard if required.
<sect> <idx/ForeignObj/ <p>
This module is provided by GHC but not by Hugs.
GreenCard for Hugs provides the <tt/ForeignObj/ type.
<sect> <idx/Concurrent/ <p>
This library provides the Concurrent Haskell extensions
<cite id="concurrentHaskell:popl96">.
We are grateful to the Glasgow Haskell Project for allowing us to
redistribute their implementation of this module.
<tscreen><verb>
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 ()
</verb></tscreen>
Notes:
<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:
<tscreen><verb>
main = forkIO (write 'a') >> write 'b'
where write c = putChar c >> write c
</verb></tscreen>
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.
</itemize>
<sect> <idx/Pretty/ <p>
This library contains Simon Peyton Jones' implementation of John
Hughes's pretty printer combinators.
<tscreen><verb>
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
</verb></tscreen>
<biblio files="refs" style="abbrv">
</article>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment