%************************************************************************ %* * \section[syslibs]{System libraries} \index{system libraries} \index{libraries, system} %* * This section gives an overview of the interfaces provided by the different {\em syslibs} that comes bundled with GHC. At the moment, there four different collections of system libraries: \begin{itemize} \item The GHC system library - collection of interfaces that mainly have grown out of abstractions used to implement GHC itself. \item Parts of the HBC libraries. \item The Posix interface - a mostly complete interface to OS functionality as specified by {\tt POSIX 1003.1}. Sadly, this library isn't a standard Haskell library...yet. \item The contrib libraries - oodles of numeric codes.. \end{itemize} If you provide a \tr{-syslib }\index{-syslib option} option on the command line, 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. %************************************************************************ %* * \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{verbatim} data Bag elt -- abstract emptyBag :: Bag elt unitBag :: elt -> Bag elt consBag :: elt -> Bag elt -> Bag elt snocBag :: Bag elt -> elt -> Bag elt unionBags :: Bag elt -> Bag elt -> Bag elt unionManyBags :: [Bag elt] -> Bag elt isEmptyBag :: Bag elt -> Bool elemBag :: Eq elt => elt -> 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 concatBag :: Bag (Bag a) -> Bag a foldBag :: (r -> r -> r) -> (a -> r) -> r -> Bag a -> r mapBag :: (a -> b) -> Bag a -> Bag b listToBag :: [elt] -> Bag elt bagToList :: Bag elt -> [elt] \end{verbatim} %************************************************************************ %* * \subsubsection[FiniteMap]{The @FiniteMap@ type} \index{FiniteMap module (GHC syslib)} %* * %************************************************************************ What functional programmers call a {\em finite map}, everyone else calls a {\em lookup table}. 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. \begin{verbatim} data FiniteMap key elt -- abstract -- 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 -- In the combining function, the first argument is -- the "old" element, while the second is the "new" one. 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] \end{verbatim} %************************************************************************ %* * \subsubsection[ListSetOps]{The @ListSetOps@ type} \index{ListSetOps module (GHC syslib)} %* * %************************************************************************ Just a few set-sounding operations on lists. If you want sets, use the \tr{Set} module. \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 \end{verbatim} %************************************************************************ %* * \subsubsection[Maybes]{The @Maybes@ type} \index{Maybes module (GHC syslib)} %* * %************************************************************************ The \tr{Maybe} type is in the Haskell 1.4 prelude. Moreover, the required \tr{Maybe} library provides many useful functions on \tr{Maybe}s. This (pre-1.3) module provides some more: An \tr{Either}-like type called \tr{MaybeErr}: \begin{verbatim} data MaybeErr val err = Succeeded val | Failed err \end{verbatim} Some operations to do with \tr{Maybe} (some commentary follows): \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) -- Equality predicate -> [(key,val)] -- The assoc list -> val -- Value to return on failure -> key -- The key -> val -- The corresponding value -- 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] \end{verbatim} NB: @catMaybes@ which used to be here, is now available via the standard @Maybe@ interface (@Maybe@ is an instance of @MonadPlus@). @allMaybes@ collects a list of @Justs@ into a single @Just@, returning @Nothing@ if there are any @Nothings@. @firstJust@ takes a list of @Maybes@ and returns the first @Just@ if there is one, or @Nothing@ otherwise. @assocMaybe@ looks up in an association list, returning @Nothing@ if it fails. Now, some operations to do with \tr{MaybeErr} (comments follow): \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] \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. @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[PackedString]{The @PackedString@ type} \index{PackedString module (GHC syslib)} %* * %************************************************************************ You need to \tr{import PackedString} and heave in your \tr{-syslib ghc} to use \tr{PackedString}s. The basic type and functions available are: \begin{verbatim} data PackedString -- abstract packString :: [Char] -> PackedString packStringST :: [Char] -> ST s PackedString packCBytesST :: Int -> Addr -> ST s PackedString packBytesForCST :: [Char] -> ST s (ByteArray Int) byteArrayToPS :: ByteArray Int -> PackedString unsafeByteArrayToPS :: ByteArray a -> Int -> PackedString psToByteArray :: PackedString -> ByteArray Int psToByteArrayST :: PackedString -> ST s (ByteArray Int) unpackPS :: PackedString -> [Char] \end{verbatim} We also provide a wad of list-manipulation-like functions: \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 filterPS :: (Char -> Bool) -> PackedString -> PackedString 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 elemPS :: Char -> PackedString -> Bool -- Perl-style split&join splitPS :: Char -> PackedString -> [PackedString] splitWithPS :: (Char -> Bool) -> PackedString -> [PackedString] joinPS :: PackedString -> [PackedString] -> PackedString substrPS :: PackedString -> Int -> Int -> PackedString -- pluck out a piece of a PackedString -- start and end chars you want; both 0-origin-specified \end{verbatim} %************************************************************************ %* * \subsubsection[Pretty]{The @Pretty@ type} \index{Pretty module (GHC syslib)} %* * %************************************************************************ This is the pretty-printer that is currently used in GHC: \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 \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. \begin{verbatim} data Set -- abstract -- instance of: Eq emptySet :: Set a mkSet :: Ord a => [a] -> Set a setToList :: Set a -> [a] unitSet :: a -> Set a singletonSet :: a -> Set a -- deprecated, use unitSet. union :: Ord a => Set a -> Set a -> Set a unionManySets :: Ord a => [Set a] -> Set a minusSet :: Ord a => Set a -> Set a -> Set a mapSet :: Ord a => (b -> a) -> Set b -> Set a intersect :: Ord a => Set a -> Set a -> Set a elementOf :: Ord a => a -> Set a -> Bool isEmptySet :: Set a -> Bool cardinality :: Set a -> Int \end{verbatim} %************************************************************************ %* * \subsubsection[BitSet]{The @BitSet@ interface} \index{Bitset interface (GHC syslib)} %* * %************************************************************************ 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. \begin{verbatim} data BitSet -- abstract -- instance of: emptyBS :: BitSet mkBS :: [Int] -> BitSet unitBS :: Int -> BitSet unionBS :: BitSet -> BitSet -> BitSet minusBS :: BitSet -> BitSet -> BitSet isEmptyBS :: BitSet -> Bool intersectBS :: BitSet -> BitSet -> BitSet elementBS :: Int -> BitSet -> Bool listBS :: BitSet -> [Int] \end{verbatim} %************************************************************************ %* * \subsubsection[Util]{The @Util@ type} \index{Util module (GHC syslib)} %* * %************************************************************************ Stuff that has been generally useful to use in writing the compiler. Don't be too surprised if this stuff moves/gets-renamed/etc. \begin{verbatim} -- general list processing forall :: (a -> Bool) -> [a] -> Bool exists :: (a -> Bool) -> [a] -> Bool nOfThem :: Int -> a -> [a] lengthExceeds :: [a] -> Int -> Bool isSingleton :: [a] -> Bool --paranoid zip'ing (equal length lists) 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] -- lazy in second argument zipLazy :: [a] -> [b] -> [(a,b)] mapAndUnzip :: (a -> (b, c)) -> [a] -> ([b], [c]) mapAndUnzip3 :: (a -> (b, c, d)) -> [a] -> ([b], [c], [d]) -- prefix and suffix matching on lists of characters. startsWith :: {-prefix-}String -> String -> Maybe String endsWith :: {-suffix-}String -> String -> Maybe String -- 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 -> _CMP_TAG) -> [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]) --list comparison with explicit element comparer. cmpList :: (a -> a -> Ordering) -> [a] -> [a] -> 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] \end{verbatim} %************************************************************************ %* * \subsection[C-interfaces]{Interfaces to C libraries} \index{C library interfaces} \index{interfaces, C library} %* * %************************************************************************ The GHC system library (\tr{-syslib ghc}) also provides interfaces to several useful C libraries, mostly from the GNU project. %************************************************************************ %* * \subsubsection[Readline]{The @Readline@ interface} \index{Readline library (GHC syslib)} \index{command-line editing library} %* * %************************************************************************ (Darren Moffat supplied the \tr{Readline} interface.) 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...) You'll need to link any Readlining program with \tr{-lreadline -ltermcap}, besides the usual \tr{-syslib ghc} (and \tr{-fhaskell-1.3}). The main function you'll use is: \begin{verbatim} readline :: String{-the prompt-} -> IO String \end{verbatim} If you want to mess around with Full Readline G(l)ory, we also provide: \begin{verbatim} rlInitialize, addHistory, rlBindKey, rlAddDefun, RlCallbackFunction(..), rlGetLineBuffer, rlSetLineBuffer, rlGetPoint, rlSetPoint, rlGetEnd, rlSetEnd, rlGetMark, rlSetMark, rlSetDone, rlPendingInput, rlPrompt, rlTerminalName, rlSetReadlineName, rlGetReadlineName \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: \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) \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...) \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 \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} %* * %************************************************************************ (Darren Moffat supplied the network-interface toolkit.) Your best bet for documentation is to look at the code---really!--- normally in \tr{hslibs/ghc/src/{BSD,Socket,SocketPrim}.lhs}. 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 () \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... 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! The interface is relatively modest: \begin{verbatim} connectTo :: Hostname -> PortID -> IO Handle listenOn :: PortID -> IO Socket accept :: Socket -> IO (Handle, HostName) sendTo :: Hostname -> PortID -> String -> IO () recvFrom :: Hostname -> PortID -> IO String socketPort :: Socket -> IO PortID 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 type Hostname = String \end{verbatim} Various examples of networking Haskell code are provided in %\tr{ghc/misc/examples/}, notably the \tr{net???/Main.hs} programs. %************************************************************************ %* * \subsection[Posix-library]{The Posix system library} \index{Posix system library} \index{system library, Posix} %* * %************************************************************************ The @Posix@ interface gives you access to the set of OS services standardised by POSIX 1003.1b (or the {\em IEEE Portable Operating System Interface for Computing Environments} - IEEE Std. 1003.1). The interface is accessed by \tr{import Posix} and adding \tr{-syslib posix} on your command-line. \subsubsection[Posix data types]{Posix data types} \index{Posix, data types} \begin{verbatim} data ByteCount -- instances of : Eq Ord Num Real Integral Ix Enum Show \end{verbatim} A \tr{ByteCount} is a primitive of type \tr{unsigned}. At a minimum, an conforming implementation must support values in the range \tr{[0, UINT_MAX]}. \begin{verbatim} data ClockTick -- instances of : Eq Ord Num Real Integral Ix Enum Show \end{verbatim} A \tr{ClockTick} is a primitive of type \tr{clock_t}, which is used to measure intervals of time in fractions of a second. The resolution is determined by \tr{getSysVar ClockTick}. \begin{verbatim} data DeviceID -- instances of : Eq Ord Num Real Integral Ix Enum Show \end{verbatim} A \tr{DeviceID} is a primitive of type \tr{dev_t}. It must be an arithmetic type. \begin{verbatim} data EpochTime -- instances of : Eq Ord Num Real Integral Ix Enum Show \end{verbatim} A \tr{EpochTime} is a primitive of type \tr{time_t}, which is used to measure seconds since the Epoch. At a minimum, the implementation must support values in the range \tr{[0, INT_MAX]}. \begin{verbatim} data FileID -- instances of : Eq Ord Num Real Integral Ix Enum Show \end{verbatim} A \tr{FileID} is a primitive of type \tr{ino_t}. It must be an arithmetic type. \begin{verbatim} data FileMode -- instances of : Eq Ord Num Real Integral Ix Enum Show \end{verbatim} A \tr{FileMode} is a primitive of type \tr{mode_t}. It must be an arithmetic type. \begin{verbatim} data FileOffset -- instances of : Eq Ord Num Real Integral Ix Enum Show \end{verbatim} A \tr{FileOffset} is a primitive of type \tr{off_t}. It must be an arithmetic type. \begin{verbatim} data GroupID -- instances of : Eq Ord Num Real Integral Ix Enum Show \end{verbatim} A \tr{GroupID} is a primitive of type \tr{gid_t}. It must be an arithmetic type. \begin{verbatim} data Limit -- instances of : Eq Ord Num Real Integral Ix Enum Show \end{verbatim} A \tr{Limit} is a primitive of type \tr{long}. At a minimum, the implementation must support values in the range \tr{[LONG_MIN, LONG_MAX]}. \begin{verbatim} data LinkCount -- instances of : Eq Ord Num Real Integral Ix Enum Show \end{verbatim} A \tr{LinkCount} is a primitive of type \tr{nlink_t}. It must be an arithmetic type. \begin{verbatim} data ProcessID -- instances of : Eq Ord Num Real Integral Ix Enum Show type ProcessGroupID = ProcessID \end{verbatim} A \tr{ProcessID} is a primitive of type \tr{pid_t}. It must be a signed arithmetic type. \begin{verbatim} data UserID -- instances of : Eq Ord Num Real Integral Ix Enum Show \end{verbatim} A \tr{UserID} is a primitive of type \tr{uid_t}. It must be an arithmetic type. \begin{verbatim} data DirStream \end{verbatim} A \tr{DirStream} is a primitive of type \tr{DIR *}. \begin{verbatim} data FileStatus \end{verbatim} A \tr{FileStatus} is a primitive of type \tr{struct stat}. \begin{verbatim} data GroupEntry \end{verbatim} A \tr{GroupEntry} is a primitive of type \tr{struct group}. \begin{verbatim} data ProcessTimes \end{verbatim} \tr{ProcessTimes} is a primitive structure containing a \tr{clock_t} and a \tr{struct tms}. \begin{verbatim} data SignalSet \end{verbatim} An \tr{SignalSet} is a primitive of type \tr{sigset_t}. \begin{verbatim} data SystemID \end{verbatim} A \tr{SystemID} is a primitive of type \tr{struct utsname}. \begin{verbatim} data TerminalAttributes \end{verbatim} \tr{TerminalAttributes} is a primitive of type \tr{struct termios}. \begin{verbatim} data UserEntry \end{verbatim} A \tr{UserEntry} is a primitive of type \tr{struct passwd}. \begin{verbatim} data BaudRate = B0 | B50 | B75 | B110 | B134 | B150 | B200 | B300 | B600 | B1200 | B1800 | B2400 | B4800 | B9600 | B19200 | B38400 deriving (Eq, Show) data Fd intToFd :: Int -> Fd -- use with care. data FdOption = AppendOnWrite | CloseOnExec | NonBlockingRead data ControlCharacter = EndOfFile | EndOfLine | Erase | Interrupt | Kill | Quit | Suspend | Start | Stop type ErrorCode = Int type FileLock = (LockRequest, SeekMode, FileOffset, FileOffset) -- whence start length data FlowAction = SuspendOutput | RestartOutput | TransmitStop | TransmitStart data Handler = Default | Ignore | Catch (IO ()) data LockRequest = ReadLock | WriteLock | Unlock deriving (Eq, Show) data OpenMode = ReadOnly | WriteOnly | ReadWrite data PathVar = LinkLimit | InputLineLimit | InputQueueLimit | FileNameLimit | PathNameLimit | PipeBufferLimit | SetOwnerAndGroupIsRestricted | FileNamesAreNotTruncated data QueueSelector = InputQueue | OutputQueue | BothQueues type Signal = Int data SysVar = ArgumentLimit | ChildLimit | ClockTick | GroupLimit | OpenFileLimit | PosixVersion | HasSavedIDs | HasJobControl data TerminalMode = InterruptOnBreak -- BRKINT | MapCRtoLF -- ICRNL | IgnoreBreak -- IGNBRK | IgnoreCR -- IGNCR | IgnoreParityErrors -- IGNPAR | MapLFtoCR -- INLCR | CheckParity -- INPCK | StripHighBit -- ISTRIP | StartStopInput -- IXOFF | StartStopOutput -- IXON | MarkParityErrors -- PARMRK | ProcessOutput -- OPOST | LocalMode -- CLOCAL | ReadEnable -- CREAD | TwoStopBits -- CSTOPB | HangupOnClose -- HUPCL | EnableParity -- PARENB | OddParity -- PARODD | EnableEcho -- ECHO | EchoErase -- ECHOE | EchoKill -- ECHOK | EchoLF -- ECHONL | ProcessInput -- ICANON | ExtendedFunctions -- IEXTEN | KeyboardInterrupts -- ISIG | NoFlushOnInterrupt -- NOFLSH | BackgroundWriteInterrupt -- TOSTOP data TerminalState = Immediately | WhenDrained | WhenFlushed data ProcessStatus = Exited ExitCode | Terminated Signal | Stopped Signal deriving (Eq, Show) \end{verbatim} \subsubsection[Process Primitives]{Posix Process Primitives} \begin{verbatim} forkProcess :: IO (Maybe ProcessID) \end{verbatim} \tr{forkProcess} calls \tr{fork}, returning \tr{Just pid} to the parent, where \tr{pid} is the ProcessID of the child, and returning \tr{Nothing} to the child. \begin{verbatim} executeFile :: FilePath -- Command -> Bool -- Search PATH? -> [String] -- Arguments -> Maybe [(String, String)] -- Environment -> IO () \end{verbatim} \tr{executeFile cmd args env} calls one of the \tr{execv*} family, depending on whether or not the current PATH is to be searched for the command, and whether or not an environment is provided to supersede the process's current environment. The basename (leading directory names suppressed) of the command is passed to \tr{execv*} as \tr{arg[0]}; the argument list passed to \tr{executeFile} therefore begins with \tr{arg[1]}. \begin{verbatim} Search PATH? Supersede environ? Call ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~ ~~~~~~~ False False execv False True execve True False execvp True True execvpe* \end{verbatim} Note that \tr{execvpe} is not provided by the POSIX standard, and must be written by hand. Care must be taken to ensure that the search path is extracted from the original environment, and not from the environment to be passed on to the new image. A successful \tr{executeFile} overlays the current process image with a new one, so it only returns on failure. \begin{verbatim} runProcess :: FilePath -- Command -> [String] -- Arguments -> Maybe [(String, String)] -- Environment (Nothing -> Inherited) -> Maybe FilePath -- Working directory (Nothing -> inherited) -> Maybe Handle -- stdin (Nothing -> inherited) -> Maybe Handle -- stdout (Nothing -> inherited) -> Maybe Handle -- stderr (Nothing -> inherited) -> IO () \end{verbatim} \tr{runProcess} is our candidate for the high-level OS-independent primitive. \tr{runProcess cmd args env wd inhdl outhdl errhdl} runs \tr{cmd} (searching the current \tr{PATH}) with arguments \tr{args}. If \tr{env} is \tr{Just pairs}, the command is executed with the environment specified by \tr{pairs} of variables and values; otherwise, the command is executed with the current environment. If \tr{wd} is \tr{Just dir}, the command is executed with working directory \tr{dir}; otherwise, the command is executed in the current working directory. If \tr{{in,out,err}hdl} is \tr{Just handle}, the command is executed with the \tr{Fd} for \tr{std{in,out,err}} attached to the specified \tr{handle}; otherwise, the \tr{Fd} for \tr{std{in,out,err}} is left unchanged. \begin{verbatim} getProcessStatus :: Bool -- Block? -> Bool -- Stopped processes? -> ProcessID -> IO (Maybe ProcessStatus) \end{verbatim} \tr{getProcessStatus blk stopped pid} calls \tr{waitpid}, returning \tr{Just tc}, the \tr{ProcessStatus} for process \tr{pid} if it is available, \tr{Nothing} otherwise. If \tr{blk} is \tr{False}, then \tr{WNOHANG} is set in the options for \tr{waitpid}, otherwise not. If \tr{stopped} is \tr{True}, then \tr{WUNTRACED} is set in the options for \tr{waitpid}, otherwise not. \begin{verbatim} getGroupProcessStatus :: Bool -- Block? -> Bool -- Stopped processes? -> ProcessGroupID -> IO (Maybe (ProcessID, ProcessStatus)) \end{verbatim} \tr{getGroupProcessStatus blk stopped pgid} calls \tr{waitpid}, returning \tr{Just (pid, tc)}, the \tr{ProcessID} and \tr{ProcessStatus} for any process in group \tr{pgid} if one is available, \tr{Nothing} otherwise. If \tr{blk} is \tr{False}, then \tr{WNOHANG} is set in the options for \tr{waitpid}, otherwise not. If \tr{stopped} is \tr{True}, then \tr{WUNTRACED} is set in the options for \tr{waitpid}, otherwise not. \begin{verbatim} getAnyProcessStatus :: Bool -- Block? -> Bool -- Stopped processes? -> IO (Maybe (ProcessID, ProcessStatus)) \end{verbatim} \tr{getAnyProcessStatus blk stopped} calls \tr{waitpid}, returning \tr{Just (pid, tc)}, the \tr{ProcessID} and \tr{ProcessStatus} for any child process if one is available, \tr{Nothing} otherwise. If \tr{blk} is \tr{False}, then \tr{WNOHANG} is set in the options for \tr{waitpid}, otherwise not. If \tr{stopped} is \tr{True}, then \tr{WUNTRACED} is set in the options for \tr{waitpid}, otherwise not. \begin{verbatim} exitImmediately :: ExitCode -> IO () \end{verbatim} \tr{exitImmediately status} calls \tr{_exit} to terminate the process with the indicated exit \tr{status}. The operation never returns. \begin{verbatim} getEnvironment :: IO [(String, String)] \end{verbatim} \tr{getEnvironment} parses the environment variable mapping provided by \tr{environ}, returning \tr{(variable, value)} pairs. The operation never fails. \begin{verbatim} setEnvironment :: [(String, String)] -> IO () \end{verbatim} \tr{setEnvironment} replaces the process environment with the provided mapping of \tr{(variable, value)} pairs. \begin{verbatim} getEnvVar :: String -> IO String \end{verbatim} \tr{getEnvVar var} returns the value associated with variable \tr{var} in the current environment (identical functionality provided through standard Haskell library function @System.getEnv@). The operation may fail with: \begin{itemize} \item[\tr{NoSuchThing}] The variable has no mapping in the current environment. \end{itemize} \begin{verbatim} setEnvVar :: String -> String -> IO () \end{verbatim} \tr{setEnvVar var val} sets the value associated with variable \tr{var} in the current environment to be \tr{val}. Any previous mapping is superseded. \begin{verbatim} removeEnvVar :: String -> IO () \end{verbatim} \tr{removeEnvVar var} removes any value associated with variable \tr{var} in the current environment. Deleting a variable for which there is no mapping does not generate an error. \begin{verbatim} nullSignal :: Signal nullSignal = 0 backgroundRead, sigTTIN :: Signal backgroundWrite, sigTTOU :: Signal continueProcess, sigCONT :: Signal floatingPointException, sigFPE :: Signal illegalInstruction, sigILL :: Signal internalAbort, sigABRT :: Signal keyboardSignal, sigINT :: Signal keyboardStop, sigTSTP :: Signal keyboardTermination, sigQUIT :: Signal killProcess, sigKILL :: Signal lostConnection, sigHUP :: Signal openEndedPipe, sigPIPE :: Signal processStatusChanged, sigCHLD :: Signal realTimeAlarm, sigALRM :: Signal segmentationViolation, sigSEGV :: Signal softwareStop, sigSTOP :: Signal softwareTermination, sigTERM :: Signal userDefinedSignal1, sigUSR1 :: Signal userDefinedSignal2, sigUSR2 :: Signal signalProcess :: Signal -> ProcessID -> IO () \end{verbatim} \tr{signalProcess int pid} calls \tr{kill} to signal process \tr{pid} with interrupt signal \tr{int}. \begin{verbatim} raiseSignal :: Signal -> IO () \end{verbatim} \tr{raiseSignal int} calls \tr{kill} to signal the current process with interrupt signal \tr{int}. \begin{verbatim} signalProcessGroup :: Signal -> ProcessGroupID -> IO () \end{verbatim} \tr{signalProcessGroup int pgid} calls \tr{kill} to signal all processes in group \tr{pgid} with interrupt signal \tr{int}. \begin{verbatim} setStoppedChildFlag :: Bool -> IO Bool \end{verbatim} \tr{setStoppedChildFlag bool} sets a flag which controls whether or not the \tr{NOCLDSTOP} option will be used the next time a signal handler is installed for \tr{SIGCHLD}. If \tr{bool} is \tr{True} (the default), \tr{NOCLDSTOP} will not be used; otherwise it will be. The operation never fails. \begin{verbatim} queryStoppedChildFlag :: IO Bool \end{verbatim} \tr{queryStoppedChildFlag} queries the flag which controls whether or not the \tr{NOCLDSTOP} option will be used the next time a signal handler is installed for \tr{SIGCHLD}. If \tr{NOCLDSTOP} will be used, it returns \tr{False}; otherwise (the default) it returns \tr{True}. The operation never fails. \begin{verbatim} emptySignalSet :: SignalSet fullSignalSet :: SignalSet addSignal :: Signal -> SignalSet -> SignalSet deleteSignal :: Signal -> SignalSet -> SignalSet inSignalSet :: Signal -> SignalSet -> Bool installHandler :: Signal -> Handler -> Maybe SignalSet -- other signals to block -> IO Handler -- old handler \end{verbatim} \tr{installHandler int handler iset} calls \tr{sigaction} to install an interrupt handler for signal \tr{int}. If \tr{handler} is \tr{Default}, \tr{SIG_DFL} is installed; if \tr{handler} is \tr{Ignore}, \tr{SIG_IGN} is installed; if \tr{handler} is \tr{Catch action}, a handler is installed which will invoke \tr{action} as a replacement for \tr{main}. If \tr{iset} is \tr{Just s}, then the \tr{sa_mask} of the \tr{sigaction} structure is set to \tr{s}; otherwise it is cleared. The previously installed signal handler for \tr{int} is returned. \begin{verbatim} getSignalMask :: IO SignalSet \end{verbatim} \tr{getSignalMask} calls \tr{sigprocmask} to determine the set of interrupts which are currently being blocked. \begin{verbatim} setSignalMask :: SignalSet -> IO SignalSet \end{verbatim} \tr{setSignalMask mask} calls \tr{sigprocmask} with \tr{SIG_SETMASK} to block all interrupts in \tr{mask}. The previous set of blocked interrupts is returned. \begin{verbatim} blockSignals :: SignalSet -> IO SignalSet \end{verbatim} \tr{setSignalMask mask} calls \tr{sigprocmask} with \tr{SIG_BLOCK} to add all interrupts in \tr{mask} to the set of blocked interrupts. The previous set of blocked interrupts is returned. \begin{verbatim} unBlockSignals :: SignalSet -> IO SignalSet \end{verbatim} \tr{setSignalMask mask} calls \tr{sigprocmask} with \tr{SIG_UNBLOCK} to remove all interrupts in \tr{mask} from the set of blocked interrupts. The previous set of blocked interrupts is returned. \begin{verbatim} getPendingSignals :: IO SignalSet \end{verbatim} \tr{getPendingSignals} calls \tr{sigpending} to obtain the set of interrupts which have been received but are currently blocked. \begin{verbatim} awaitSignal :: Maybe SignalSet -> IO () \end{verbatim} \tr{awaitSignal iset} suspends execution until an interrupt is received. If \tr{iset} is \tr{Just s}, \tr{awaitSignal} calls \tr{sigsuspend}, installing \tr{s} as the new signal mask before suspending execution; otherwise, it calls \tr{pause}. If successful, \tr{awaitSignal} does not return. \begin{verbatim} scheduleAlarm :: Int -> IO Int \end{verbatim} \tr{scheduleAlarm i} calls \tr{alarm} to schedule a real time alarm at least \tr{i} seconds in the future. \begin{verbatim} sleep :: Int -> IO () \end{verbatim} \tr{sleep i} calls \tr{sleep} to suspend execution of the program until at least \tr{i} seconds have elapsed or a signal is received. \subsubsection[Process Environment]{Posix Process Environment} \index{Posix, process environment} \begin{verbatim} getProcessID :: IO ProcessID \end{verbatim} \tr{getProcessID} calls \tr{getpid} to obtain the \tr{ProcessID} for the current process. \begin{verbatim} getParentProcessID :: IO ProcessID \end{verbatim} \tr{getProcessID} calls \tr{getppid} to obtain the \tr{ProcessID} for the parent of the current process. \begin{verbatim} getRealUserID :: IO UserID \end{verbatim} \tr{getRealUserID} calls \tr{getuid} to obtain the real \tr{UserID} associated with the current process. \begin{verbatim} getEffectiveUserID :: IO UserID \end{verbatim} \tr{getRealUserID} calls \tr{geteuid} to obtain the effective \tr{UserID} associated with the current process. \begin{verbatim} setUserID :: UserID -> IO () \end{verbatim} \tr{setUserID uid} calls \tr{setuid} to set the real, effective, and saved set-user-id associated with the current process to \tr{uid}. \begin{verbatim} getLoginName :: IO String \end{verbatim} \tr{getLoginName} calls \tr{getlogin} to obtain the login name associated with the current process. \begin{verbatim} getRealGroupID :: IO GroupID \end{verbatim} \tr{getRealGroupID} calls \tr{getgid} to obtain the real \tr{GroupID} associated with the current process. \begin{verbatim} getEffectiveGroupID :: IO GroupID \end{verbatim} \tr{getEffectiveGroupID} calls \tr{getegid} to obtain the effective \tr{GroupID} associated with the current process. \begin{verbatim} setGroupID :: GroupID -> IO () \end{verbatim} \tr{setGroupID gid} calls \tr{setgid} to set the real, effective, and saved set-group-id associated with the current process to \tr{gid}. \begin{verbatim} getGroups :: IO [GroupID] \end{verbatim} \tr{getGroups} calls \tr{getgroups} to obtain the list of supplementary \tr{GroupID}s associated with the current process. \begin{verbatim} getEffectiveUserName :: IO String \end{verbatim} \tr{getEffectiveUserName} calls \tr{cuserid} to obtain a name associated with the effective \tr{UserID} of the process. \begin{verbatim} getProcessGroupID :: IO ProcessGroupID \end{verbatim} \tr{getProcessGroupID} calls \tr{getpgrp} to obtain the \tr{ProcessGroupID} for the current process. \begin{verbatim} createProcessGroup :: ProcessID -> IO ProcessGroupID \end{verbatim} \tr{createProcessGroup pid} calls \tr{setpgid} to make process \tr{pid} a new process group leader. \begin{verbatim} joinProcessGroup :: ProcessGroupID -> IO ProcessGroupID \end{verbatim} \tr{joinProcessGroup pgid} calls \tr{setpgid} to set the \tr{ProcessGroupID} of the current process to \tr{pgid}. \begin{verbatim} setProcessGroupID :: ProcessID -> ProcessGroupID -> IO () \end{verbatim} \tr{setProcessGroupID pid pgid} calls \tr{setpgid} to set the \tr{ProcessGroupID} for process \tr{pid} to \tr{pgid}. \begin{verbatim} createSession :: IO ProcessGroupID \end{verbatim} \tr{createSession} calls \tr{setsid} to create a new session with the current process as session leader. \begin{verbatim} systemName :: SystemID -> String nodeName :: SystemID -> String release :: SystemID -> String version :: SystemID -> String machine :: SystemID -> String getSystemID :: IO SystemID \end{verbatim} \tr{getSystemID} calls \tr{uname} to obtain information about the current operating system. \begin{verbatim} > epochTime :: IO EpochTime \end{verbatim} \tr{epochTime} calls \tr{time} to obtain the number of seconds that have elapsed since the epoch (Jan 01 00:00:00 GMT 1970). \begin{verbatim} elapsedTime :: ProcessTimes -> ClockTick userTime :: ProcessTimes -> ClockTick systemTime :: ProcessTimes -> ClockTick childUserTime :: ProcessTimes -> ClockTick childSystemTime :: ProcessTimes -> ClockTick getProcessTimes :: IO ProcessTimes \end{verbatim} \tr{getProcessTimes} calls \tr{times} to obtain time-accounting information for the current process and its children. \begin{verbatim} getControllingTerminalName :: IO FilePath \end{verbatim} \tr{getControllingTerminalName} calls \tr{ctermid} to obtain a name associated with the controlling terminal for the process. If a controlling terminal exists, \tr{getControllingTerminalName} returns the name of the controlling terminal. The operation may fail with: \begin{itemize} \item[\tr{NoSuchThing}] There is no controlling terminal, or its name cannot be determined. \item[\tr{SystemError}] Various other causes. \end{itemize} \begin{verbatim} getTerminalName :: Fd -> IO FilePath \end{verbatim} \tr{getTerminalName fd} calls \tr{ttyname} to obtain a name associated with the terminal for \tr{Fd} \tr{fd}. If \tr{fd} is associated with a terminal, \tr{getTerminalName} returns the name of the terminal. The operation may fail with: \begin{itemize} \item[\tr{InappropriateType}] The channel is not associated with a terminal. \item[\tr{NoSuchThing}] The channel is associated with a terminal, but it has no name. \item[\tr{SystemError}] Various other causes. \end{itemize} \begin{verbatim} queryTerminal :: Fd -> IO Bool \end{verbatim} \tr{queryTerminal fd} calls \tr{isatty} to determine whether or not \tr{Fd} \tr{fd} is associated with a terminal. \begin{verbatim} getSysVar :: SysVar -> IO Limit \end{verbatim} \tr{getSysVar var} calls \tr{sysconf} to obtain the dynamic value of the requested configurable system limit or option. For defined system limits, \tr{getSysVar} returns the associated value. For defined system options, the result of \tr{getSysVar} is undefined, but not failure. The operation may fail with: \begin{itemize} \item[\tr{NoSuchThing}] The requested system limit or option is undefined. \end{itemize} \subsubsection[Files and Directories]{Posix operations on files and directories} \index{Posix, files and directories} \begin{verbatim} openDirStream :: FilePath -> IO DirStream \end{verbatim} \tr{openDirStream dir} calls \tr{opendir} to obtain a directory stream for \tr{dir}. \begin{verbatim} readDirStream :: DirStream -> IO String \end{verbatim} \tr{readDirStream dp} calls \tr{readdir} to obtain the next directory entry (\tr{struct dirent}) for the open directory stream \tr{dp}, and returns the \tr{d_name} member of that structure. The operation may fail with: \begin{itemize} \item[\tr{EOF}] End of file has been reached. \item[\tr{SystemError}] Various other causes. \end{itemize} \begin{verbatim} rewindDirStream :: DirStream -> IO () \end{verbatim} \tr{rewindDirStream dp} calls \tr{rewinddir} to reposition the directory stream \tr{dp} at the beginning of the directory. \begin{verbatim} closeDirStream :: DirStream -> IO () \end{verbatim} \tr{closeDirStream dp} calls \tr{closedir} to close the directory stream \tr{dp}. \begin{verbatim} getWorkingDirectory :: IO FilePath \end{verbatim} \tr{getWorkingDirectory} calls \tr{getcwd} to obtain the name of the current working directory. \begin{verbatim} changeWorkingDirectory :: FilePath -> IO () \end{verbatim} \tr{changeWorkingDirectory dir} calls \tr{chdir} to change the current working directory to \tr{dir}. \begin{verbatim} nullFileMode :: FileMode -- --------- ownerReadMode :: FileMode -- r-------- ownerWriteMode :: FileMode -- -w------- ownerExecuteMode :: FileMode -- --x------ groupReadMode :: FileMode -- ---r----- groupWriteMode :: FileMode -- ----w---- groupExecuteMode :: FileMode -- -----x--- otherReadMode :: FileMode -- ------r-- otherWriteMode :: FileMode -- -------w- otherExecuteMode :: FileMode -- --------x setUserIDMode :: FileMode -- --S------ setGroupIDMode :: FileMode -- -----S--- stdFileMode :: FileMode -- rw-rw-rw- ownerModes :: FileMode -- rwx------ groupModes :: FileMode -- ---rwx--- otherModes :: FileMode -- ------rwx accessModes :: FileMode -- rwxrwxrwx unionFileModes :: FileMode -> FileMode -> FileMode intersectFileModes :: FileMode -> FileMode -> FileMode stdInput :: Fd stdInput = intToFd 0 stdOutput :: Fd stdOutput = intToFd 1 stdError :: Fd stdError = intToFd 2 data OpenFileFlags = OpenFileFlags { append :: Bool, exclusive :: Bool, noctty :: Bool, nonBlock :: Bool, trunc :: Bool } openFd :: FilePath -> OpenMode -> Maybe FileMode -- Just x => O_CREAT, Nothing => must exist -> OpenFileFlags -> IO Fd \end{verbatim} \tr{openFd path acc mode (OpenFileFlags app excl noctty nonblock trunc)} calls \tr{open} to obtain a \tr{Fd} for the file \tr{path} with access mode \tr{acc}. If \tr{mode} is \tr{Just m}, the \tr{O_CREAT} flag is set and the file's permissions will be based on \tr{m} if it does not already exist; otherwise, the \tr{O_CREAT} flag is not set. The arguments \tr{app}, \tr{excl}, \tr{noctty}, \tr{nonblock}, and \tr{trunc} control whether or not the flags \tr{O_APPEND}, \tr{O_EXCL}, \tr{O_NOCTTY}, \tr{O_NONBLOCK}, and \tr{O_TRUNC} are set, respectively. \begin{verbatim} createFile :: FilePath -> FileMode -> IO Fd \end{verbatim} \tr{createFile path mode} calls \tr{creat} to obtain a \tr{Fd} for file \tr{path}, which will be created with permissions based on \tr{mode} if it does not already exist. \begin{verbatim} setFileCreationMask :: FileMode -> IO FileMode \end{verbatim} \tr{setFileCreationMask mode} calls \tr{umask} to set the process's file creation mask to \tr{mode}. The previous file creation mask is returned. \begin{verbatim} createLink :: FilePath -> FilePath -> IO () \end{verbatim} \tr{createLink old new} calls \tr{link} to create a new path, \tr{new}, linked to an existing file, \tr{old}. \begin{verbatim} createDirectory :: FilePath -> FileMode -> IO () \end{verbatim} \tr{createDirectory dir mode} calls \tr{mkdir} to create a new directory, \tr{dir}, with permissions based on \tr{mode}. \begin{verbatim} createNamedPipe :: FilePath -> FileMode -> IO () \end{verbatim} \tr{createNamedPipe fifo mode} calls \tr{mkfifo} to create a new named pipe, \tr{fifo}, with permissions based on \tr{mode}. \begin{verbatim} removeLink :: FilePath -> IO () \end{verbatim} \tr{removeLink path} calls \tr{unlink} to remove the link named \tr{path}. \begin{verbatim} removeDirectory :: FilePath -> IO () \end{verbatim} \tr{removeDirectory dir} calls \tr{rmdir} to remove the directory named \tr{dir}. \begin{verbatim} rename :: FilePath -> FilePath -> IO () \end{verbatim} \tr{rename old new} calls \tr{rename} to rename a file or directory from \tr{old} to \tr{new}. \begin{verbatim} fileMode :: FileStatus -> FileMode fileID :: FileStatus -> FileID deviceID :: FileStatus -> DeviceID linkCount :: FileStatus -> LinkCount fileOwner :: FileStatus -> UserID fileGroup :: FileStatus -> GroupID fileSize :: FileStatus -> FileOffset accessTime :: FileStatus -> EpochTime modificationTime :: FileStatus -> EpochTime statusChangeTime :: FileStatus -> EpochTime isDirectory :: FileStatus -> Bool isCharacterDevice :: FileStatus -> Bool isBlockDevice :: FileStatus -> Bool isRegularFile :: FileStatus -> Bool isNamedPipe :: FileStatus -> Bool getFileStatus :: FilePath -> IO FileStatus \end{verbatim} \tr{getFileStatus path} calls \tr{stat} to get the \tr{FileStatus} information for the file \tr{path}. \begin{verbatim} getFdStatus :: Fd -> IO FileStatus \end{verbatim} \tr{getFdStatus fd} calls \tr{fstat} to get the \tr{FileStatus} information for the file associated with \tr{Fd} \tr{fd}. \begin{verbatim} queryAccess :: FilePath -> Bool -> Bool -> Bool -> IO Bool \end{verbatim} \tr{queryAccess path r w x} calls \tr{access} to test the access permissions for file \tr{path}. The three arguments, \tr{r}, \tr{w}, and \tr{x} control whether or not \tr{access} is called with \tr{R_OK}, \tr{W_OK}, and \tr{X_OK} respectively. \begin{verbatim} queryFile :: FilePath -> IO Bool \end{verbatim} \tr{queryFile path} calls \tr{access} with \tr{F_OK} to test for the existence for file \tr{path}. \begin{verbatim} setFileMode :: FilePath -> FileMode -> IO () \end{verbatim} \tr{setFileMode path mode} calls \tr{chmod} to set the permission bits associated with file \tr{path} to \tr{mode}. \begin{verbatim} setOwnerAndGroup :: FilePath -> UserID -> GroupID -> IO () \end{verbatim} \tr{setOwnerAndGroup path uid gid} calls \tr{chown} to set the \tr{UserID} and \tr{GroupID} associated with file \tr{path} to \tr{uid} and \tr{gid}, respectively. \begin{verbatim} setFileTimes :: FilePath -> EpochTime -> EpochTime -> IO () \end{verbatim} \tr{setFileTimes path atime mtime} calls \tr{utime} to set the access and modification times associated with file \tr{path} to \tr{atime} and \tr{mtime}, respectively. \begin{verbatim} touchFile :: FilePath -> IO () \end{verbatim} \tr{touchFile path} calls \tr{utime} to set the access and modification times associated with file \tr{path} to the current time. \begin{verbatim} getPathVar :: PathVar -> FilePath -> IO Limit \end{verbatim} \tr{getPathVar var path} calls \tr{pathconf} to obtain the dynamic value of the requested configurable file limit or option associated with file or directory \tr{path}. For defined file limits, \tr{getPathVar} returns the associated value. For defined file options, the result of \tr{getPathVar} is undefined, but not failure. The operation may fail with: \begin{itemize} \item[\tr{NoSuchThing}] The requested file limit or option is undefined. \item[\tr{SystemError}] Various other causes. \end{itemize} \begin{verbatim} getFdVar :: PathVar -> Fd -> IO Limit \end{verbatim} \tr{getFdVar var fd} calls \tr{fpathconf} to obtain the dynamic value of the requested configurable file limit or option associated with the file or directory attached to the open channel \tr{fd}. For defined file limits, \tr{getFdVar} returns the associated value. For defined file options, the result of \tr{getFdVar} is undefined, but not failure. The operation may fail with: \begin{itemize} \item[\tr{NoSuchThing}] The requested file limit or option is undefined. \item[\tr{SystemError}] Various other causes. \end{itemize} \subsubsection[Inut Output]{Posix Input and Output Primitives} \index{Posix, input/output} \begin{verbatim} createPipe :: IO (Fd, Fd) \end{verbatim} \tr{createPipe} calls \tr{pipe} to create a pipe and returns a pair of \tr{Fd}s, the first for writing and the second for reading. \begin{verbatim} dup :: Fd -> IO Fd \end{verbatim} \tr{dup fd} calls \tr{dup} to duplicate \tr{Fd} \tr{fd} to another \tr{Fd}. \begin{verbatim} dupTo :: Fd -> Fd -> IO () \end{verbatim} \tr{dupTo src dst} calls \tr{dup2} to duplicate \tr{Fd} \tr{src} to \tr{Fd} \tr{dst}. \begin{verbatim} fdClose :: Fd -> IO () \end{verbatim} \tr{fdClose fd} calls \tr{close} to close \tr{Fd} \tr{fd}. \begin{verbatim} fdRead :: Fd -> ByteCount -> IO (String, ByteCount) \end{verbatim} \tr{fdRead fd nbytes} calls \tr{read} to read at most \tr{nbytes} bytes from \tr{Fd} \tr{fd}, and returns the result as a string paired with the number of bytes actually read. The operation may fail with: \begin{itemize} \item[\tr{EOF}] End of file has been reached. \item[\tr{SystemError}] Various other causes. \end{itemize} \begin{verbatim} fdWrite :: Fd -> String -> IO ByteCount \end{verbatim} \tr{fdWrite fd s} calls \tr{write} to write the string \tr{s} to \tr{Fd} \tr{fd} as a contiguous sequence of bytes. It returns the number of bytes successfully written. \begin{verbatim} queryFdOption :: FdOption -> Fd -> IO Bool \end{verbatim} \tr{getFdOption opt fd} calls \tr{fcntl} to determine whether or not the flag associated with \tr{FdOption} \tr{opt} is set for \tr{Fd} \tr{fd}. \begin{verbatim} setFdOption :: Fd -> FdOption -> Bool -> IO () \end{verbatim} \tr{setFdOption fd opt val} calls \tr{fcntl} to set the flag associated with \tr{FdOption} \tr{opt} on \tr{Fd} \tr{fd} to \tr{val}. \begin{verbatim} getLock :: Fd -> FileLock -> IO (Maybe (ProcessID, FileLock)) \end{verbatim} \tr{getLock fd lock} calls \tr{fcntl} to get the first \tr{FileLock} for \tr{Fd} \tr{fd} which blocks the \tr{FileLock} \tr{lock}. If no such \tr{FileLock} exists, \tr{getLock} returns \tr{Nothing}. Otherwise, it returns \tr{Just (pid, block)}, where \tr{block} is the blocking \tr{FileLock} and \tr{pid} is the \tr{ProcessID} of the process holding the blocking \tr{FileLock}. \begin{verbatim} setLock :: Fd -> FileLock -> IO () \end{verbatim} \tr{setLock fd lock} calls \tr{fcntl} with \tr{F_SETLK} to set or clear a lock segment for \tr{Fd} \tr{fd} as indicated by the \tr{FileLock} \tr{lock}. \tr{setLock} does not block, but fails with \tr{SystemError} if the request cannot be satisfied immediately. \begin{verbatim} waitToSetLock :: Fd -> FileLock -> IO () \end{verbatim} \tr{waitToSetLock fd lock} calls \tr{fcntl} with \tr{F_SETLKW} to set or clear a lock segment for \tr{Fd} \tr{fd} as indicated by the \tr{FileLock} \tr{lock}. If the request cannot be satisfied immediately, \tr{waitToSetLock} blocks until the request can be satisfied. \begin{verbatim} fdSeek :: Fd -> SeekMode -> FileOffset -> IO FileOffset \end{verbatim} \tr{fdSeek fd whence offset} calls \tr{lseek} to position the \tr{Fd} \tr{fd} at the given \tr{offset} from the starting location indicated by \tr{whence}. It returns the resulting offset from the start of the file in bytes. \subsubsection[Device Specific Functions]{Posix, Device- and Class-Specific Functions} \index{Posix, device and class-specific functions} \begin{verbatim} terminalMode :: TerminalMode -> TerminalAttributes -> Bool withMode :: TerminalAttributes -> TerminalMode -> TerminalAttributes withoutMode :: TerminalAttributes -> TerminalMode -> TerminalAttributes bitsPerByte :: TerminalAttributes -> Int withBits :: TerminalAttributes -> Int -> TerminalAttributes controlChar :: TerminalAttributes -> ControlCharacter -> Maybe Char withCC :: TerminalAttributes -> (ControlCharacter, Char) -> TerminalAttributes withoutCC :: TerminalAttributes -> ControlCharacter -> TerminalAttributes inputTime :: TerminalAttributes -> Int withTime :: TerminalAttributes -> Int -> TerminalAttributes minInput :: TerminalAttributes -> Int withMinInput :: TerminalAttributes -> Int -> TerminalAttributes inputSpeed :: TerminalAttributes -> BaudRate withInputSpeed :: TerminalAttributes -> BaudRate -> TerminalAttributes outputSpeed :: TerminalAttributes -> BaudRate withOutputSpeed :: TerminalAttributes -> BaudRate -> TerminalAttributes getTerminalAttributes :: Fd -> IO TerminalAttributes \end{verbatim} \tr{getTerminalAttributes fd} calls \tr{tcgetattr} to obtain the \tr{TerminalAttributes} associated with \tr{Fd} \tr{fd}. \begin{verbatim} setTerminalAttributes :: Fd -> TerminalAttributes -> TerminalState -> IO () \end{verbatim} \tr{setTerminalAttributes fd attr ts} calls \tr{tcsetattr} to change the \tr{TerminalAttributes} associated with \tr{Fd} \tr{fd} to \tr{attr}, when the terminal is in the state indicated by \tr{ts}. \begin{verbatim} sendBreak :: Fd -> Int -> IO () \end{verbatim} \tr{sendBreak fd duration} calls \tr{tcsendbreak} to transmit a continuous stream of zero-valued bits on \tr{Fd} \tr{fd} for the specified implementation-dependent \tr{duration}. \begin{verbatim} drainOutput :: Fd -> IO () \end{verbatim} \tr{drainOutput fd} calls \tr{tcdrain} to block until all output written to \tr{Fd} \tr{fd} has been transmitted. \begin{verbatim} discardData :: Fd -> QueueSelector -> IO () \end{verbatim} \tr{discardData fd queues} calls \tr{tcflush} to discard pending input and/or output for \tr{Fd} \tr{fd}, as indicated by the \tr{QueueSelector} \tr{queues}. \begin{verbatim} controlFlow :: Fd -> FlowAction -> IO () \end{verbatim} \tr{controlFlow fd action} calls \tr{tcflow} to control the flow of data on \tr{Fd} \tr{fd}, as indicated by \tr{action}. \begin{verbatim} getTerminalProcessGroupID :: Fd -> IO ProcessGroupID \end{verbatim} \tr{getTerminalProcessGroupID fd} calls \tr{tcgetpgrp} to obtain the \tr{ProcessGroupID} of the foreground process group associated with the terminal attached to \tr{Fd} \tr{fd}. \begin{verbatim} setTerminalProcessGroupID :: Fd -> ProcessGroupID -> IO () \end{verbatim} \tr{setTerminalProcessGroupID fd pgid} calls \tr{tcsetpgrp} to set the \tr{ProcessGroupID} of the foreground process group associated with the terminal attached to \tr{Fd} \tr{fd} to \tr{pgid}. \subsubsection[System Database]{Posix System Databases} \index{Posix, system databases} \begin{verbatim} groupName :: GroupEntry -> String groupID :: GroupEntry -> GroupID groupMembers :: GroupEntry -> [String] getGroupEntryForID :: GroupID -> IO GroupEntry \end{verbatim} \tr{getGroupEntryForID gid} calls \tr{getgrgid} to obtain the \tr{GroupEntry} information associated with \tr{GroupID} \tr{gid}. The operation may fail with: \begin{itemize} \item[\tr{NoSuchThing}] There is no group entry for the GroupID. \end{itemize} \begin{verbatim} getGroupEntryForName :: String -> IO GroupEntry \end{verbatim} \tr{getGroupEntryForName name} calls \tr{getgrnam} to obtain the \tr{GroupEntry} information associated with the group called \tr{name}. The operation may fail with: \begin{itemize} \item[\tr{NoSuchThing}] There is no group entry for the name. \end{itemize} \begin{verbatim} userName :: UserEntry -> String userID :: UserEntry -> UserID userGroupID :: UserEntry -> GroupID homeDirectory :: UserEntry -> String userShell :: UserEntry -> String getUserEntryForID :: UserID -> IO UserEntry \end{verbatim} \tr{getUserEntryForID gid} calls \tr{getpwuid} to obtain the \tr{UserEntry} information associated with \tr{UserID} \tr{uid}. The operation may fail with: \begin{itemize} \item[\tr{NoSuchThing}] There is no user entry for the UserID. \end{itemize} \begin{verbatim} getUserEntryForName :: String -> IO UserEntry \end{verbatim} \tr{getUserEntryForName name} calls \tr{getpwnam} to obtain the \tr{UserEntry} information associated with the user login \tr{name}. The operation may fail with: \begin{itemize} \item[\tr{NoSuchThing}] There is no user entry for the name. \end{itemize} \subsubsection[Error reporting and handling]{POSIX Errors} \index{Posix, errors} \begin{verbatim} getErrorCode :: IO ErrorCode \end{verbatim} \tr{getErrorCode} returns the current value of the external variable \tr{errno}. It never fails. \begin{verbatim} setErrorCode :: ErrorCode -> IO () \end{verbatim} \tr{setErrorCode err} sets the external variable \tr{errno} to \tr{err}. It never fails. \begin{verbatim} noError :: ErrorCode noError = 0 argumentListTooLong, e2BIG :: ErrorCode badFd, eBADF :: ErrorCode brokenPipe, ePIPE :: ErrorCode directoryNotEmpty, eNOTEMPTY :: ErrorCode execFormatError, eNOEXEC :: ErrorCode fileAlreadyExists, eEXIST :: ErrorCode fileTooLarge, eFBIG :: ErrorCode filenameTooLong, eNAMETOOLONG :: ErrorCode improperLink, eXDEV :: ErrorCode inappropriateIOControlOperation, eNOTTY :: ErrorCode inputOutputError, eIO :: ErrorCode interruptedOperation, eINTR :: ErrorCode invalidArgument, eINVAL :: ErrorCode invalidSeek, eSPIPE :: ErrorCode isADirectory, eISDIR :: ErrorCode noChildProcess, eCHILD :: ErrorCode noLocksAvailable, eNOLCK :: ErrorCode noSpaceLeftOnDevice, eNOSPC :: ErrorCode noSuchOperationOnDevice, eNODEV :: ErrorCode noSuchDeviceOrAddress, eNXIO :: ErrorCode noSuchFileOrDirectory, eNOENT :: ErrorCode noSuchProcess, eSRCH :: ErrorCode notADirectory, eNOTDIR :: ErrorCode notEnoughMemory, eNOMEM :: ErrorCode operationNotImplemented, eNOSYS :: ErrorCode operationNotPermitted, ePERM :: ErrorCode permissionDenied, eACCES :: ErrorCode readOnlyFileSystem, eROFS :: ErrorCode resourceBusy, eBUSY :: ErrorCode resourceDeadlockAvoided, eDEADLK :: ErrorCode resourceTemporarilyUnavailable, eAGAIN :: ErrorCode tooManyLinks, eMLINK :: ErrorCode tooManyOpenFiles, eMFILE :: ErrorCode tooManyOpenFilesInSystem, eNFILE :: ErrorCode \end{verbatim} %************************************************************************ %* * \subsection[HBC-library]{The HBC system library} \index{HBC system library} \index{system library, HBC} %* * %************************************************************************ This documentation is stolen directly from the HBC distribution. The modules that GHC does not support (because they require HBC-specific extensions) are omitted. \begin{description} \item[\tr{Either}:] \index{Either module (HBC library)}% A binary sum data type: \begin{verbatim} data Either a b = Left a | Right b \end{verbatim} The constructor \tr{Left} is typically used for errors; it can be renamed to \tr{Wrong} on import. \item[\tr{Maybe}:] \index{Maybe module (HBC library)}% A type for failure or success: \begin{verbatim} data Maybe a = Nothing | Just a thenM :: Maybe a -> (a -> Maybe b) -> Maybe b -- apply a function that may fail \end{verbatim} \item[\tr{Option}:] \index{Option module (HBC library)}% An alias for \tr{Maybe}: \begin{verbatim} data Option a = None | Some a thenO :: Option a -> (a -> Option b) -> Option b \end{verbatim} \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 :: (Text a) => String -> [a] -- read a list in a lazy fashion \end{verbatim} \item[\tr{Pretty}:] \index{Pretty module (HBC library)}% John Hughes's pretty printing library. \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 \end{verbatim} \item[\tr{QSort}:] \index{QSort module (HBC library)}% A sort function using quicksort. \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 \end{verbatim} \item[\tr{Random}:] \index{Random module (HBC library)}% Random numbers. \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 \end{verbatim} \item[\tr{Trace}:] Simple tracing. (Note: This comes with GHC anyway.) \begin{verbatim} trace :: String -> a -> a -- trace x y prints x and returns y \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{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 Text Byte, Text Short, Text 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 \end{verbatim} \item[\tr{TimeUtil}:] \index{Time module (HBC library)}% Manipulate time values (a Double with seconds since 1970). [7/97 -- this lib has been more or less superceeded by the standard Time interface] \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 \end{verbatim} \item[\tr{Hash}:] \index{Hash module (HBC library)}% Hashing functions. \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] \end{verbatim} \item[\tr{NameSupply}:] \index{NameSupply module (HBC library)}% Functions to generate unique names (Int). \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 \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. \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, Text 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 :: (Text a) => (Parser [a] b) -> [a] -> Either String b -- Simple parse. Return error message or result. \end{verbatim} %%%simpleLex :: String -> [String] -- A simple (but useful) lexical analyzer \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. \end{verbatim} \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. \end{verbatim} \end{description}