Commit a2d6e018 authored by Simon Peyton Jones's avatar Simon Peyton Jones
Browse files

Late Dec release

parent ab3899f5
This diff is collapsed.
......@@ -160,12 +160,13 @@ subArray bnds = ixmap bnds (\i->i)
-- A row of a matrix
row :: (Ix a, Ix b) => a -> Array (a,b) c -> Array b c
row i x = ixmap (l',u') (\j->(i,j)) x where ((l,l'),(u,u')) = bounds x
row i x = ixmap (l',u') (\j->(i,j)) x where ((_,l'),(_,u')) = bounds x
-- Diagonal of a square matrix
-- Diagonal of a matrix (assumed to be square)
diag :: (Ix a) => Array (a,a) b -> Array a b
diag x = ixmap (l,u) (\i->(i,i)) x
where ((l,l'),(u,u')) | l == l' && u == u' = bounds x
where
((l,_),(u,_)) = bounds x
-- Projection of first components of an array of pairs
firstArray :: (Ix a) => Array a (b,c) -> Array a b
......
......@@ -66,7 +66,17 @@ range.
The function @showLitChar@ converts a character to a string using
only printable characters, using Haskell source-language escape conventions.
The function @readLitChar@ does the reverse.
The function @lexLitChar@ does the reverse, returning the sequence of characters
that encode the character.
The function @readLitChar@ does the same, but in addition converts the
to the character that it encodes. For example:
\bprog
@
showLitChar '\n' s = "\\n" ++ s
lexLitChar "\\nHello" = [("\\n", "Hello")]
readLitChar "\\nHello" = [("\n", "Hello")]
@
\eprog
Function @toUpper@ converts a letter to the corresponding
upper-case letter, leaving any other character unchanged. Any
......
......@@ -10,9 +10,9 @@ module Char (
Char, String
) where
import Array -- used for character name table.
import Array -- Used for character name table.
import Numeric (readDec, readOct, lexDigits, readHex)
import UnicodePrims -- source of primitive Unicode functions.
import UnicodePrims -- Source of primitive Unicode functions.
-- Character-testing operations
isAscii, isControl, isPrint, isSpace, isUpper, isLower,
......
module IO where
module IO {- export list omitted -} where
-- Just provide an implementation of the system-indendent
-- actions that IO exports.
......
......@@ -14,7 +14,7 @@ module List (
unzip4, unzip5, unzip6, unzip7, unfoldr,
-- ...and what the Prelude exports
[]((:), []),
-- []((:), []), -- This is built-in syntax
map, (++), concat, filter,
head, last, tail, init, null, length, (!!),
foldl, foldl1, scanl, scanl1, foldr, foldr1, scanr, scanr1,
......@@ -69,7 +69,7 @@ union :: Eq a => [a] -> [a] -> [a]
union = unionBy (==)
unionBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]
unionBy eq xs ys = xs ++ foldl (flip (deleteBy eq)) (nubBy eq ys) xs
unionBy eq xs ys = xs ++ deleteFirstsBy eq (nubBy eq ys) xs
intersect :: Eq a => [a] -> [a] -> [a]
intersect = intersectBy (==)
......@@ -83,15 +83,15 @@ intersperse sep [x] = [x]
intersperse sep (x:xs) = x : sep : intersperse sep xs
-- transpose is lazy in both rows and columns,
-- and works for non-rectangular 'matrices'
-- and works for non-rectangular 'matrices'
-- For example, transpose [[1,2],[3,4,5],[]] = [[1,3],[2,4],[5]]
-- Note that [h | (h:t) <- xss] is not the same as (map head xss)
-- because the former discards empty sublists inside xss
-- because the former discards empty sublists inside xss
transpose :: [[a]] -> [[a]]
transpose [] = []
transpose [] = []
transpose ([] : xss) = transpose xss
transpose ((x:xs) : xss) = (x : [h | (h:t) <- xss]) :
transpose (xs : [t | (h:t) <- xss])
transpose (xs : [t | (h:t) <- xss])
partition :: (a -> Bool) -> [a] -> ([a],[a])
partition p xs = (filter p xs, filter (not . p) xs)
......@@ -139,10 +139,10 @@ mapAccumR f s (x:xs) = (s'', y:ys)
where (s'',y ) = f s' x
(s', ys) = mapAccumR f s xs
unfoldr :: (b -> Maybe (a,b)) -> b -> [a]
unfoldr f b = case f b of
Nothing -> []
Just (a,b) -> a : unfoldr f b
unfoldr :: (b -> Maybe (a,b)) -> b -> [a]
unfoldr f b = case f b of
Nothing -> []
Just (a,b) -> a : unfoldr f b
sort :: (Ord a) => [a] -> [a]
sort = sortBy compare
......@@ -150,8 +150,8 @@ sort = sortBy compare
sortBy :: (a -> a -> Ordering) -> [a] -> [a]
sortBy cmp = foldr (insertBy cmp) []
insert :: (Ord a) => a -> [a] -> [a]
insert = insertBy compare
insert :: (Ord a) => a -> [a] -> [a]
insert = insertBy compare
insertBy :: (a -> a -> Ordering) -> a -> [a] -> [a]
insertBy cmp x [] = [x]
......@@ -163,18 +163,18 @@ insertBy cmp x ys@(y:ys')
maximumBy :: (a -> a -> Ordering) -> [a] -> a
maximumBy cmp [] = error "List.maximumBy: empty list"
maximumBy cmp xs = foldl1 max xs
where
max x y = case cmp x y of
GT -> x
_ -> y
where
max x y = case cmp x y of
GT -> x
_ -> y
minimumBy :: (a -> a -> Ordering) -> [a] -> a
minimumBy cmp [] = error "List.minimumBy: empty list"
minimumBy cmp xs = foldl1 min xs
where
min x y = case cmp x y of
GT -> y
_ -> x
where
min x y = case cmp x y of
GT -> y
_ -> x
genericLength :: (Integral a) => [b] -> a
genericLength [] = 0
......
module Numeric(fromRat,
showSigned, showInt,
showSigned, showIntAtBase,
showInt, showOct, showHex,
readSigned, readInt,
readDec, readOct, readHex,
floatToDigits,
......@@ -84,18 +85,29 @@ integerLogBase b i =
-- Misc utilities to show integers and floats
showSigned :: Real a => (a -> ShowS) -> Int -> a -> ShowS
showSigned showPos p x | x < 0 = showParen (p > 6)
(showChar '-' . showPos (-x))
| otherwise = showPos x
-- showInt is used for positive numbers only
showInt :: Integral a => a -> ShowS
showInt n r | n < 0 = error "Numeric.showInt: can't show negative numbers"
| otherwise =
let (n',d) = quotRem n 10
r' = toEnum (fromEnum '0' + fromIntegral d) : r
in if n' == 0 then r' else showInt n' r'
showSigned :: Real a => (a -> ShowS) -> Int -> a -> ShowS
showSigned showPos p x
| x < 0 = showParen (p > 6) (showChar '-' . showPos (-x))
| otherwise = showPos x
-- showInt, showOct, showHex are used for positive numbers only
showInt, showOct, showHex :: Integral a => a -> ShowS
showOct = showIntAtBase 8 intToDigit
showInt = showIntAtBase 10 intToDigit
showHex = showIntAtBase 16 intToDigit
showIntAtBase :: Integral a
=> a -- base
-> (Int -> Char) -- digit to char
-> a -- number to show
-> ShowS
showIntAtBase base intToDig n rest
| n < 0 = error "Numeric.showIntAtBase: can't show negative numbers"
| n' == 0 = rest'
| otherwise = showIntAtBase base intToDig n' rest'
where
(n',d) = quotRem n base
rest' = intToDig (fromIntegral d) : rest
readSigned :: (Real a) => ReadS a -> ReadS a
......
`%**<title>The Haskell 98 Library Report: Directory functions</title>
%**<title>The Haskell 98 Library Report: Directory functions</title>
%**~header
%% Other useful functions from SML 96 include modification time
......@@ -42,10 +42,11 @@ Computation @createDirectory@~"dir" creates a new directory "dir" which is
initially empty, or as near to empty as the operating system allows.
\index{making directories}
{\em Error~reporting}:
the @createDirectory@ computation may fail with:
{\em Error~reporting}.
The @createDirectory@ computation may fail with:
@isPermissionError@ if the user is not permitted to create the directory;
@isAlreadyExistsError@ if the directory already exists.
@isAlreadyExistsError@ if the directory already exists; or @isDoesNotExistError@ if
the new directory's parent does not exist.
Computation @removeDirectory@~"dir" removes an existing directory
"dir"\index{deleting directories}\index{removing directories}. The
......@@ -63,8 +64,8 @@ files}\index{removing files}. The implementation may specify additional
constraints which must be satisfied before a file can be removed (for instance, the
file may not be in use by other processes).
{\em Error~reporting}:
the @removeDirectory@ and @removeFile@ computations may fail with:
{\em Error~reporting}.
The @removeDirectory@ and @removeFile@ computations may fail with:
@isPermissionError@ if the user is not permitted to remove the file/directory;
or @isDoesNotExistError@ if the file/directory does not exist.
......@@ -86,21 +87,22 @@ implementation need not support renaming files in all situations
(for instance, renaming across different physical devices), but the constraints must be
documented.
{\em Error~reporting}:
the @renameDirectory@ and @renameFile@ computations may fail with:
{\em Error~reporting}.
The @renameDirectory@ and @renameFile@ computations may fail with:
@isPermissionError@ if the user is not permitted to rename the file/directory,
or if either argument to @renameFile@ is a directory;
or @isDoesNotExistError@ if the file/directory does not exist.
Computation @getDirectoryContents@~"dir" returns a list of {\em all} entries
in "dir"\index{reading a directory}.
Each entry in the returned list is named relative to the directory "dir", not as an absolute path.
If the operating system has a notion of current directories,
@getCurrentDirectory@ returns an absolute path to the
current directory of the calling process\index{current directory}.
{\em Error~reporting}:
the @getDirectoryContents@ and @getCurrentDirectory@ computations may fail with:
{\em Error~reporting}.
The @getDirectoryContents@ and @getCurrentDirectory@ computations may fail with:
@isPermissionError@ if the user is not permitted to access the directory;
or @isDoesNotExistError@ if the directory does not exist.
......@@ -108,8 +110,8 @@ If the operating system has a notion of current directories,
@setCurrentDirectory@~"dir" changes the current directory of the
calling process to "dir"\index{changing the directory}\index{setting the directory}.
{\em Error~reporting}:
the @setCurrentDirectory@ computation may fail with:
{\em Error~reporting}.
@setCurrentDirectory@ may fail with:
@isPermissionError@ if the user is not permitted to change directory
to that specified;
or @isDoesNotExistError@ if the directory does not exist.
......@@ -140,11 +142,11 @@ if the argument file exists and is not a directory, and @False@ otherwise.
The @getModificationTime@ operation returns the
clock time at which the file/directory was last modified.
{\em Error~reporting}:
the @get(set)Permissions@,
{\em Error~reporting}.
@get(set)Permissions@,
@doesFile(Directory)Exist@,
and @getModificationTime@
computations may fail with:
may fail with:
@isPermissionError@ if the user is not permitted to access
the appropriate information;
or @isDoesNotExistError@ if the file/directory does not exist.
......
......@@ -4,7 +4,7 @@ module Char (
digitToInt, intToDigit,
toUpper, toLower,
ord, chr,
readLitChar, showLitChar, lexLitChar
readLitChar, showLitChar, lexLitChar,
-- ...and what the Prelude exports
Char, String
......
......@@ -14,7 +14,7 @@ module IO (
isFullError, isEOFError,
isIllegalOperation, isPermissionError, isUserError,
ioeGetErrorString, ioeGetHandle, ioeGetFileName,
try, bracket, bracket_
try, bracket, bracket_,
-- ...and what the Prelude exports
IO, FilePath, IOError, ioError, userError, catch, interact,
......
......@@ -14,7 +14,7 @@ module List (
unzip4, unzip5, unzip6, unzip7, unfoldr,
-- ...and what the Prelude exports
[]((:), []),
-- []((:), []), -- This is built-in syntax
map, (++), concat, filter,
head, last, tail, init, null, length, (!!),
foldl, foldl1, scanl, scanl1, foldr, foldr1, scanr, scanr1,
......
module Numeric(fromRat,
showSigned, showInt,
showSigned, showIntAtBase,
showInt, showOct, showHex,
readSigned, readInt,
readDec, readOct, readHex,
floatToDigits,
......@@ -7,8 +8,13 @@ module Numeric(fromRat,
readFloat, lexDigits) where
fromRat :: (RealFloat a) => Rational -> a
showSigned :: (Real a) => (a -> ShowS) -> Int -> a -> ShowS
showIntAtBase :: Integral a => a -> (Int -> Char) -> a -> ShowS
showInt :: Integral a => a -> ShowS
showOct :: Integral a => a -> ShowS
showHex :: Integral a => a -> ShowS
readSigned :: (Real a) => ReadS a -> ReadS a
readInt :: (Integral a) =>
a -> (Char -> Bool) -> (Char -> Int) -> ReadS a
......
......@@ -33,7 +33,7 @@ style=article
~back=<a href="~prev.html">back</a>
~nxt=<a href="~next.html">next</a>
~contents=<a href="libindex.html">contents</a>
~foot=<br><font size=2>October 2001</font>
~foot=<br><font size=2>December 2001</font>
~footer=<hr>~id~top | ~back | ~nxt | ~contents ~foot
~sfooter=<hr>~id~top | back | ~nxt | ~contents ~foot
~efooter=<hr>~id~top | ~back | next | ~contents ~foot
......
......@@ -7,7 +7,7 @@
<img src="h98-libs.gif" alt="Haskell 98 Libraries">
<h3 align="center">Standard Libraries for Haskell 98</h3>
<h3 align="center">Revised: October 2001</h3>
<h3 align="center">Revised: December 2001</h3>
</div>
<hr>
<h3>Table of Contents</h3>
......
......@@ -92,7 +92,6 @@ computation. This is similar to try-catch-finally in Java.
% Inline the code here since there's no other functions in IO that
% are not primitive.
\inputHS{code/IO}
\subsection{Files and Handles}
......@@ -181,7 +180,7 @@ or once the entire contents of the handle has been read.
Once a semi-closed handle becomes closed, the contents of the
associated list becomes fixed. The contents of this final list is
only partially specified: it will contain at least all the items of
the stream that were evalutated prior to the handle becoming closed.
the stream that were evaluated prior to the handle becoming closed.
Any I/O errors encountered while a handle is semi-closed are simply
discarded.
......@@ -559,8 +558,8 @@ main = do
x2 <- readNum
putStr ("Their sum is " ++ show (x1+x2) ++ "\n")
where readNum :: IO Integer
-- Need a type signature for
-- readLn to avoid ambiguity
-- Providing a type signature avoids reliance on
-- the defaulting rule to fix the type of x1,x2
readNum = readLn
@
\eprog
......@@ -575,6 +574,7 @@ Note that exactly two arguments must be supplied to the program.
@
import IO
import System
import Char( toUpper )
main = do
[f1,f2] <- getArgs
......@@ -598,6 +598,7 @@ An equivalent but much shorter version, using string I/O is:
\bprog
@
import System
import Char( toUpper )
main = do
[f1,f2] <- getArgs
......@@ -616,5 +617,8 @@ main = do
% the @~@, a class error would occur because there is no instance of
% @IO@ for class @MonadZero@.
\subsection{Library @IO@}
\inputHS{code/IO}
%**~footer
%
% $Header: /home/cvs/root/haskell-report/libraries/library.verb,v 1.11 2001/10/02 09:09:26 simonpj Exp $
% $Header: /home/cvs/root/haskell-report/libraries/library.verb,v 1.12 2001/12/21 16:00:22 simonpj Exp $
%
% NOTE:--------------------------------------------------------------
% The formatting of this report and the ``new font selection scheme''
......@@ -380,7 +380,7 @@
%\newcommand{\subsubsubsection}[1]{\par\noindent{\it #1}}
\newcommand{\subsubsubsection}{\subsubsection*}
%\sloppy
\sloppy
% a few hyphenation patterns, anyone?
\hyphenation{da-ta-type da-ta-types}
......@@ -412,7 +412,7 @@
{\Large\bf for the} \\[.1in]
{\huge\bf Haskell 98} \\[.3in]
{\LARGE\bf Programming Language} \\[.3in]
{\large\bf Revised: October 2001}
{\large\bf Revised: December 2001}
\end{center}
\vspace{.15in}
......@@ -456,7 +456,7 @@ Copyright (c) Simon Peyton Jones.
{\em The authors intend this Report to belong to the entire Haskell
community, and so we grant permission to copy and distribute it for
any purpose, provided that it is reproduced in its entireity,
any purpose, provided that it is reproduced in its entirety,
including this Notice. Modified versions of this Report may also be
copied and distributed for any purpose, provided that the modified
version is clearly presented as such, and that it does not claim to be
......
......@@ -13,18 +13,20 @@ This library defines some lesser-used operations over lists.
\subsection{Indexing lists}
Function @elemIndex val list@\indextt{elemIndex} returns the index of
\begin{itemize}
\item @elemIndex val list@\indextt{elemIndex} returns the index of
the first occurrence, if any, of @val@
in @list@ as @Just index@. @Nothing@ is returned if @not (val `elem` list)@.
Function @elemIndices val list@\indextt{elemIndices} returns an
\item @elemIndices val list@\indextt{elemIndices} returns an
in-order list of indices, giving the occurrences of @val@ in @list@.
Function @find@\indextt{find}
\item @find@\indextt{find}
returns the first element of a list that satisfies a predicate,
or Nothing, if there is no such element.
@findIndex@ returns the corresponding index.
@findIndices@ returns a list of all such indices.
\end{itemize}
\subsection{``Set'' operations}
......@@ -109,14 +111,18 @@ predicate, respectively; i.e.,
\eprog
\item
@sort@/@sortBy@\indextt{sort}\indextt{sortBy}
@sort@\indextt{sort}
implement a stable sorting algorithm, here specified
in terms of the @insertBy@ function, which inserts objects into a list
according to the specified ordering relation.
\item
@insert@\indextt{insert}
inserts a new element into an {\em ordered} list (arranged in increasing order).
\item
@group@\indextt{group} splits its list argument into a list of lists of equal, adjacent
elements. For exmaple
elements. For example
\bprog
@
group "Mississippi" == ["M","i","ss","i","ss","i","pp","i"]
......@@ -209,8 +215,21 @@ function replaces an @Ord@ context by a binary predicate, the
predicate is assumed to define a total ordering.
The ``@By@'' variants are as follows:
@nubBy@, @deleteBy@, @unionBy@, @intersectBy@, @groupBy@,
@sortBy@, @insertBy@, @maximumBy@, @minimumBy@. The library does not
@nubBy@, @deleteBy@, @deleteFirstsBy@ (the "@By@" variant of @\\@),
@unionBy@, @intersectBy@, @groupBy@,
@sortBy@, @insertBy@, @maximumBy@, @minimumBy@.
\indextt{nubBy}
\indextt{deleteBy}
\indextt{deleteFirstsBy}
\indextt{unionBy}
\indextt{intersectBy}
\indextt{groupBy}
\indextt{sortBy}
\indextt{insertBy}
\indextt{maximumBy}
\indextt{minimumBy}
The library does not
provide @elemBy@, because @any (eq x)@ does the same job as @elemBy eq x@ would.
A handful of overloaded functions (@elemIndex@, @elemIndices@, @isPrefixOf@, @isSuffixOf@)
were not considered important enough to have ``@By@'' variants.
......@@ -234,9 +253,16 @@ is a generalised verion of @length@.
The ``@generic@'' operations are as follows:
@genericLength@, @genericTake@, @genericDrop@,
@genericSplitAt@, @genericIndex@, @genericReplicate@.
@genericSplitAt@, @genericIndex@ (the generic version of @!!@), @genericReplicate@.
\subsection{Further ``@zip@'' operations}
The Prelude provides @zip@, @zip3@, @unzip@, @unzip3@, @zipWith@, and @zipWith3@.
The List library provides these same three operations for 4, 5, 6, and 7 arguments.
\indextt{zip4}
\indextt{unzip4}
\indextt{zipWith4}
\clearpage
\subsection{Library {\tt List}}
......
......@@ -20,8 +20,8 @@ A postfix ``@M@'' always stands for a function in the Kleisli category:
So, for example,
\bprog
@
filter :: (a -> Bool) -> [a] -> [a]
filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
filter :: (a -> Bool) -> [a] -> [a]
filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]
@
\eprog
......@@ -49,7 +49,7 @@ Thus, for example:
The @MonadPlus@ class is defined as follows:
\bprog
@
class (Monad m) => MonadPlus m where
class Monad m => MonadPlus m where
mzero :: m a
mplus :: m a -> m a -> m a
@
......@@ -90,7 +90,7 @@ each line with its line number,
@
listFile :: String -> IO ()
listFile nm =
do cts <- openFile nm
do cts <- readFile nm
zipWithM_ (\i line -> do putStr (show i); putStr ": "; putStrLn line)
[1..]
(lines cts)
......
......@@ -25,7 +25,12 @@ possibly-negative @Real@ value of type @a@ to a string. In the call "(@showSign
"val" is the value to show, "prec" is the precedence of the enclosing context, and "show" is
a function that can show unsigned values.
\item @showInt :: Integral a => a -> ShowS@ \\ shows {\em unsigned} @Integral@ values of type @a@.
\item @showIntAtBase :: Integral a => a -> (Int -> Char) -> a -> ShowS@ \\
shows a {\em non-negative} @Integral@ number using the base specified by the first argument,
and the character representation specified by the second.
\item @showInt, showOct, showHex :: Integral a => a -> ShowS@ \\
show {\em non-negative} @Integral@ numbers in base 10, 8, and 16 respectively.
\item
@showFFloat, showEFloat, showGFloat@ \\
......@@ -71,6 +76,8 @@ each read an unsigned number, in decimal, octal, and hexadecimal notation respec
In the hexadecimal case, both upper or lower case letters are allowed.
\item @lexDigits :: ReadS String@ reads a non-empty string of decimal digits.
\end{itemize}
(NB: @readInt@ is the ``dual'' of @showIntAtBase@, and @readDec@ is the ``dual'' of @showInt@.
The inconsistent naming is a historical accident.)
\subsection{Miscellaneous}
......
......@@ -48,7 +48,7 @@ the generator.
It is required that:
\begin{itemize}
\item If $(a,b) ~=~ @genRange@~ g$, then $a \leq b$.
\item If $(a,b) ~=~ @genRange@~ g$, then $a < b$.
\item $@genRange@~\bot ~\neq~ \bot$.
\end{itemize}
The second condition ensures that @genRange@ cannot examine its
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment