Commit bc981f79 authored by Simon Marlow's avatar Simon Marlow
Browse files

switch to new Haddock-generated library docs

parent b11426b3
......@@ -7,12 +7,14 @@
##########################################
# What to make if you type 'make'
default: haskell.pdf html
default: pdf html
.PHONY: pdf
pdf : haskell.pdf
# Begin by saying
# touch haskell.idx
#########################################
# Tools you need
#########################################
......@@ -55,37 +57,49 @@ PARTS_NO_PREFACE = iso-chars.tex \
derived.tex \
index-extra.tex index-intro.tex layout.tex fixity.tex \
literate.tex pragmas.tex standard-prelude.tex \
ratio.tex complex.tex ix.tex \
numeric.tex \
array.tex io.tex char.tex monad.tex list.tex \
system.tex directory.tex \
maybe.tex time.tex cputime.tex random.tex \
locale.tex syntax-lexical.tex syntax-iso.tex ffi.tex \
syntax-lexical.tex syntax-iso.tex ffi.tex \
Prelude.tex PreludeList.tex PreludeText.tex PreludeIO.tex \
lib-marshal.tex \
lib-cerror.tex lib-data-intword.tex lib-marshalerror.tex \
lib-cforeign.tex lib-foreignptr.tex lib-marshalutils.tex \
lib-cstring.tex lib-foreign.tex lib-ptr.tex \
lib-ctypes.tex lib-marshalalloc.tex lib-stableptr.tex \
lib-data-bits.tex lib-marshalarray.tex lib-storable.tex
CODE = lib-code/Ratio.tex lib-code/Complex.tex lib-code/Ix.tex \
lib-code/Numeric.tex \
lib-code/Array.tex lib-code/Char.tex lib-code/List.tex \
lib-code/Monad.tex lib-code/Maybe.tex lib-code/IO.tex \
lib-code/Time.tex lib-code/Locale.tex
HEADERS = lib-hdrs/Ratio.tex lib-hdrs/Complex.tex lib-hdrs/Ix.tex \
lib-hdrs/Numeric.tex \
lib-hdrs/Array.tex lib-hdrs/IO.tex lib-hdrs/Char.tex \
lib-hdrs/List.tex lib-hdrs/List1.tex \
lib-hdrs/Monad.tex lib-hdrs/System.tex lib-hdrs/Directory.tex \
lib-hdrs/Maybe.tex lib-hdrs/IO1.tex lib-hdrs/Random.tex \
lib-hdrs/Time.tex lib-hdrs/Time1.tex lib-hdrs/CPUTime.tex \
lib-hdrs/Locale.tex
$(LIB_TEX)
LIB_MODULES = Data.Array \
Data.Char \
Data.Complex \
System.IO \
System.IO.Error \
Data.Ix \
Data.List \
Data.Maybe \
Control.Monad \
Data.Ratio \
System.Environment \
System.Exit \
Data.Int \
Data.Word \
Data.Bits \
Foreign \
Foreign.Ptr \
Foreign.ForeignPtr \
Foreign.StablePtr \
Foreign.Storable \
Foreign.C \
Foreign.C.Error \
Foreign.C.String \
Foreign.C.Types \
Foreign.Marshal \
Foreign.Marshal.Alloc \
Foreign.Marshal.Array \
Foreign.Marshal.Error \
Foreign.Marshal.Utils
HADDOCK_ODIR = libs
LIB_TEX = $(patsubst %, $(HADDOCK_ODIR)/%, $(addsuffix .tex, $(subst .,-,$(LIB_MODULES))))
HT_TEXS = $(patsubst %, ht/%, $(PARTS))
show:
@echo '$(VALUE)="$($(VALUE))"'
#########################################
# Main targets
#########################################
......@@ -105,8 +119,8 @@ haskell.tex: haskell.verb
# $(RUN_INDEX)
# cp index.html *.png *.gif haskell-report-html
haskell.dvi: haskell.tex haskell.ind ${PARTS} ${CODE} ${HEADERS}
haskell.pdf: haskell.tex haskell.ind ${PARTS} ${CODE} ${HEADERS}
haskell.dvi: haskell.tex haskell.ind ${PARTS}
haskell.pdf: haskell.tex haskell.ind haddock-style.tex ${PARTS}
haskell.ps : haskell.dvi
dvips haskell.dvi -o haskell.ps
......@@ -135,21 +149,15 @@ publish-pdf: report.pdf
ht/classes.eps : classes.eps
$(CP) $< $@
ht/lib-hdrs :
$(RM) $@
$(LN) ../lib-hdrs ht/lib-hdrs
ht/lib-code :
$(RM) $@
$(LN) ../lib-code ht/lib-code
html: $(HT_TEXS) ht/classes.eps ht/lib-hdrs ht/lib-code
.PHONY: html
html: $(HT_TEXS) ht/classes.eps ht/haddock-style.tex
cd ht && htlatex haskell.tex "haskell,2"
#########################################
# Generic stuff
#########################################
.PHONY: clean veryclean
veryclean: clean
$(RM) *~
......@@ -189,6 +197,9 @@ clean:
ht/%.tex: %.verb
$(EXPAND) < $< | $(VERB_TEX4HT) | sh ../tools/subsection >$@
ht/libs/%.tex: libs/%.tex
$(CP) $< $@
jfp: h98-book.tex preface-jfp.tex ${PARTS_NO_PREFACE}
-mkdir $(JFP_DIR)
for n in h98-book.tex preface-jfp.tex \
......@@ -242,3 +253,16 @@ haskell-libraries-2up.dvi : haskell-librariesx.dvi
haskell-librariesx.dvi : sigplan_haskell-libraries.dvi
dviselect =4: sigplan_haskell-libraries.dvi haskell-librariesx.dvi
# -----------------------------------------------------------------------------
# Haddock-generated library docs
HADDOCK = /64playpen/simonmar/testing/inplace/bin/haddock
GHC_BUILD = /home/simonmar/builds/testing
LIB_PKG_DIR = $(GHC_BUILD)/libraries/haskell2010
HADDOCK_GHC_OPTS = --optghc=-package-name --optghc=haskell2010-1.0.0.0 --optghc=-hide-all-packages --optghc=-i --optghc=-i$(GHC_BUILD)/libraries/haskell2010/. --optghc=-i$(GHC_BUILD)/libraries/haskell2010/dist-install/build --optghc=-i$(GHC_BUILD)/libraries/haskell2010/dist-install/build/autogen --optghc=-i$(GHC_BUILD)/Libraries/haskell2010/dist-install/build --optghc=-i$(GHC_BUILD)/Libraries/haskell2010/dist-install/build/autogen --optghc=-i$(GHC_BUILD)/Libraries/haskell2010/. --optghc=-optP-include --optghc=-optP$(GHC_BUILD)/libraries/haskell2010/dist-install/build/autogen/cabal_macros.h --optghc=-package --optghc=array-0.3.0.0 --optghc=-package --optghc=base-4.3.0.0 --optghc=-package-name --optghc=haskell2010 --optghc=-XPackageImports --optghc=-XCPP --optghc=-no-user-package-conf --optghc=-rtsopts --optghc=-O --optghc=-fasm --optghc=-dcore-lint --optghc=-fno-warn-deprecated-flags --optghc=-odir --optghc=libraries/haskell2010/dist-install/build --optghc=-hidir --optghc=$(GHC_BUILD)/libraries/haskell2010/dist-install/build --optghc=-stubdir --optghc=$(GHC_BUILD)/libraries/haskell2010/dist-install/build --optghc=-hisuf --optghc=hi --optghc=-osuf --optghc=o --optghc=-hcsuf --optghc=hc
haddock :
$(HADDOCK) --odir=$(HADDOCK_ODIR) --no-tmp-comp-dir --latex --title="haskell2010-1.0.0.0: Compatibility with Haskell 2010" --read-interface=../ghc-prim,$(GHC_BUILD)/libraries/ghc-prim/dist-install/doc/html/ghc-prim/ghc-prim.haddock --read-interface=../array-0.3.0.0,$(GHC_BUILD)/libraries/array/dist-install/doc/html/array/array.haddock --read-interface=../base-4.3.0.0,$(GHC_BUILD)/libraries/base/dist-install/doc/html/base/base.haddock $(HADDOCK_GHC_OPTS) $(patsubst %, $(LIB_PKG_DIR)/%, $(addsuffix .hs, $(subst .,/,$(LIB_MODULES))))
%**<title>The Haskell 98 Library Report: Arrays</title>
%**~header
\section{Arrays}
\label{arrays}
\index{array}
\outline{
\inputHS{lib-hdrs/Array}
}
\Haskell{} provides indexable {\em arrays}, which may be thought of as
functions whose domains are isomorphic to contiguous subsets of the
integers.
Functions restricted in this way can be
implemented efficiently; in particular, a programmer may
reasonably expect rapid access to the components. To ensure
the possibility of such an implementation, arrays are treated as data, not as
general functions.
Since most array functions involve the class @Ix@, this module is
exported from @Array@ so that modules need not import both @Array@ and
@Ix@.
\subsection{Array Construction}
If @a@ is an index type and @b@ is any type, the type of arrays with
indices in @a@ and elements in @b@ is written @Array a b@.\indextycon{Array}
An array may be created by the function @array@\indextt{array}.
The first argument of @array@ is a pair of {\em bounds}, each of the
index type of the array. These bounds are the lowest and
highest indices in the array, in that order. For example, a
one-origin vector of length @10@ has bounds @(1,10)@, and a one-origin @10@
by @10@ matrix has bounds @((1,1),(10,10))@.
The second argument of @array@ is a list of {\em associations}
of the form ($index$,~$value$). Typically, this list will
be expressed as a comprehension. An association @(i, x)@ defines the
value of the array at index @i@ to be @x@. The array is undefined (i.e.~$\bot$) if
any index in the list is out of bounds. If any two associations in the
list have the same index, the value at that index is undefined (i.e.~$\bot$).
Because the indices must be checked for these errors, @array@ is
strict in the bounds argument and in the indices of the association list,
but nonstrict in the values. Thus, recurrences such as the following are
possible:
\bprog
@
a = array (1,100) ((1,1) : [(i, i * a!(i-1)) | i <- [2..100]])
@
\eprog
Not every index within the bounds of the array need
appear in the association list, but the values associated with indices
that do not appear will be undefined (i.e.~$\bot$).
Figure~\ref{array-examples} shows some examples that use the
@array@ constructor.
\begin{figure}[tb]
\begin{outlineenv}\small
@
-- Scaling an array of numbers by a given number:
scale :: (Num a, Ix b) => a -> Array b a -> Array b a
scale x a = array b [(i, a!i * x) | i <- range b]
where b = bounds a
-- Inverting an array that holds a permutation of its indices
invPerm :: (Ix a) => Array a a -> Array a a
invPerm a = array b [(a!i, i) | i <- range b]
where b = bounds a
-- The inner product of two vectors
inner :: (Ix a, Num b) => Array a b -> Array a b -> b
inner v w = if b == bounds w
then sum [v!i * w!i | i <- range b]
else error "inconformable arrays for inner product"
where b = bounds v
@
\end{outlineenv}
\ecaption{Array examples}
\label{array-examples}
\end{figure}
The @(!)@\index{""!@@{\tt {\char'041}}} operator denotes array subscripting.
% array subscripting -- if the index lies outside the bounds of the
% array, the result is undefined.
The @bounds@\indextt{bounds} function
applied to an array returns its bounds.
The functions @indices@\indextt{indices}, @elems@\indextt{elems}, and
@assocs@,\indextt{assocs} when applied to an array, return lists of
the indices, elements, or associations, respectively, in index order.
An array may be constructed from a pair of bounds and a list
of values in index order using the function @listArray@\indextt{listArray}.
If, in any dimension, the lower bound is greater than the upper bound,
then the array is legal, but empty. Indexing an empty array always
gives an array-bounds error, but @bounds@ still yields the bounds
with which the array was constructed.
\subsubsection{Accumulated Arrays}
\index{array!accumulated}
Another array creation function, @accumArray@,\indextt{accumArray}
relaxes the restriction that a given index may appear at most once in
the association list, using an {\em accumulating function} which
combines the values of associations with the same index.
% \cite{nikhil:id-nouveau,wadler:array-primitive}:
The first argument of @accumArray@ is the accumulating function; the
second is an initial value; the remaining two arguments are a bounds
pair and an association list, as for the @array@ function.
For example, given a list of values of some index type, @hist@
produces a histogram of the number of occurrences of each index within
a specified range:
\bprog
@
hist :: (Ix a, Num b) => (a,a) -> [a] -> Array a b
hist bnds is = accumArray (+) 0 bnds [(i, 1) | i<-is, inRange bnds i]
@
\eprog
If the accumulating function is strict, then @accumArray@ is
strict in the values, as well as the indices, in the
association list. Thus, unlike ordinary arrays,
accumulated arrays should not in general be recursive.
\subsection{Incremental Array Updates}
\label{array-update}
The operator @(//)@\indextt{//} takes an array and a list of pairs and returns
an array identical to the left argument except that it has
been updated by the associations in the right argument. (As with
the @array@ function, the indices in the association list must
be unique for the updated elements to be defined.) For example,
if @m@ is a 1-origin, @n@ by @n@ matrix, then
@m//[((i,i), 0) | i <- [1..n]]@ is the same matrix, except with
the diagonal zeroed.
@accum@\indextt{accum} "f" takes an array
and an association list and accumulates pairs from the list into
the array with the accumulating function "f". Thus @accumArray@
can be defined using @accum@:\nopagebreak[4]
\bprog
@
accumArray f z b = accum f (array b [(i, z) | i <- range b])
@
\eprogNoSkip
\subsection{Derived Arrays}
\index{array!derived}
The two functions @fmap@\indextt{fmap} and @ixmap@\indextt{ixmap}
derive new arrays from existing ones; they may be
thought of as providing function composition on the left and right,
respectively, with the mapping that the original array embodies.
The @fmap@ function transforms the array values while
@ixmap@ allows for transformations on array indices.
Figure~\ref{derived-array-examples} shows some examples.
\begin{figure}[tb]
\begin{outlineenv}\small
@
-- A rectangular subarray
subArray :: (Ix a) => (a,a) -> Array a b -> Array a b
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'),(_,u')) = bounds x
-- 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,_),(u,_)) = bounds x
-- Projection of first components of an array of pairs
firstArray :: (Ix a) => Array a (b,c) -> Array a b
firstArray = fmap (\(x,y)->x)
@
\end{outlineenv}
\ecaption{Derived array examples}
\label{derived-array-examples}
\end{figure}
\subsection{Library {\tt Array}}
\label {Libarray}
\inputHS{lib-code/Array}
%**~footer
%**<title>The Haskell 98 Library Report: Character Utilities</title>
%**~header
\section{Character Utilities}
\outline{
\inputHS{lib-hdrs/Char}
}
\indextt{isAscii}
\indextt{isLatin1}
\indextt{isControl}
\indextt{isPrint}
\indextt{isSpace}
\indextt{isUpper}
\indextt{isLower}
\indextt{isAlpha}
\indextt{isDigit}
\indextt{isOctDigit}
\indextt{isHexDigit}
\indextt{isAlphaNum}
\indextt{toUpper}
\indextt{toLower}
This library provides a limited set of operations on the Unicode
character set.
The first 128 entries of this character set are identical to the
ASCII set; with the next 128 entries comes the remainder of the
Latin-1 character set.
This module offers only a limited view of the
full Unicode character set; the full set of Unicode character
attributes is not accessible in this library.
Unicode characters may be divided into five general categories:
non-printing, lower case alphabetic, other alphabetic, numeric digits, and
other printable characters. For the purposes of Haskell, any
alphabetic character which is not lower case is treated as upper case
(Unicode actually has three cases: upper, lower, and title). Numeric
digits may be part of identifiers but digits outside the ASCII range are not
used by the reader to represent numbers.
For each sort of Unicode character, here are the predicates which
return @True@:
\begin{center}
\begin{tabular}{|l|llll|}
\hline
Character Type & Predicates & & & \\
\hline
Lower Case Alphabetic & @isPrint@ & @isAlphaNum@ & @isAlpha@ & @isLower@ \\
Other Alphabetic & @isPrint@ & @isAlphaNum@ & @isAlpha@ & @isUpper@ \\
Digits & @isPrint@ & @isAlphaNum@ & & \\
Other Printable & @isPrint@ & & & \\
Non-printing & & & &\\
\hline
\end{tabular}
\end{center}
The @isDigit@, @isOctDigit@, and @isHexDigit@ functions select only
ASCII characters. @intToDigit@ and @digitToInt@ convert between
a single digit @Char@ and the corresponding @Int@.
@digitToInt@ operates fails unless its argument satisfies @isHexDigit@,
but recognises both upper and lower-case hexadecimal digits (i.e. @'0'@..@'9'@,
@'a'@..@'f'@, @'A'@..@'F'@). @intToDigit@ fails unless its argument is in the range
@0@..@15@, and generates lower-case hexadecimal digits.
The @isSpace@ function recognizes only white characters in the Latin-1
range.
The function @showLitChar@ converts a character to a string using
only printable characters, using Haskell source-language escape conventions.
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
Unicode letter which has an upper-case equivalent is transformed.
Similarly, @toLower@ converts a letter to the
corresponding lower-case letter, leaving any other character
unchanged.
The @ord@ and @chr@ functions are @fromEnum@ and @toEnum@
restricted to the type @Char@.
\clearpage
\subsection{Library {\tt Char}}
\label{Char}
\inputHS{lib-code/Char}
%**~footer
%**<title>The Haskell 98 Library Report: Complex Numbers</title>
%**~header
\section{Complex Numbers}
\label{lib-num}
\outline{
\inputHS{lib-hdrs/Complex}
}
Complex numbers are an algebraic type.
The constructor @(:+)@\indextt{:+} forms a complex number from its
real and imaginary rectangular components. This constructor is
strict: if either the real part or the imaginary part of the number is
$\bot$, the entire number is $\bot$. A complex number may also
be formed from polar components of magnitude and phase by the function
@mkPolar@\indextt{mkPolar}. The function @cis@\indextt{polar}
produces a complex number from an angle "t".
Put another way, @cis@ "t" is a complex value with magnitude "1"
and phase "t" (modulo "2\pi").
The function @polar@\indextt{polar} takes a complex number and
returns a (magnitude, phase) pair in canonical form: The magnitude is
nonnegative, and the phase, in the range $(- \pi , \pi ]$; if the
magnitude is zero, then so is the phase.
The functions @realPart@\indextt{realPart} and
@imagPart@\indextt{imagPart} extract the rectangular components of a
complex number and the functions @magnitude@\indextt{magnitude} and
@phase@\indextt{phase} extract the polar components of a complex
number. The function @conjugate@\indextt{conjugate} computes the
conjugate of a complex number in the usual way.
The magnitude and sign of a complex number are defined as follows:
\bprog
@
abs z = magnitude z :+ 0
signum 0 = 0
signum z@@(x:+y) = x/r :+ y/r where r = magnitude z
@
\eprog
That is, @abs@ $z$ is a number with the magnitude of $z$, but oriented
in the positive real direction, whereas @signum@ $z$ has the phase of
$z$, but unit magnitude.
\subsection{Library {\tt Complex}}
\inputHS{lib-code/Complex}
%**~footer
%**<title>The Haskell 98 Library Report: CPU Time</title>
%**~header
\section{CPU Time}
\label{cputime}
\index{CPU time}
\index{execution time}
\outline {
\inputHS{lib-hdrs/CPUTime}
}
Computation @getCPUTime@ returns the number of picoseconds of CPU time
used by the current program. The precision of this result is given by
@cpuTimePrecision@. This is the smallest measurable difference in CPU
time that the implementation can record, and is given as an integral
number of picoseconds.
%**~footer
%**<title>The Haskell 98 Library Report: Directory functions</title>
%**~header
%% Other useful functions from SML 96 include modification time
%% and path-testing (is this a full path/real path).
\section{Directory Functions}
\index{directories}
\index{the file system}
\outline{
\inputHS{lib-hdrs/Directory}
}
\indextt{createDirectory}\indextt{removeDirectory}\indextt{removeFile}
\indextt{renameDirectory}\indextt{renameFile}
\indextt{getDirectoryContents}\indextt{getCurrentDirectory}
\indextt{setCurrentDirectory}
These functions operate on directories in the file system.
Any @Directory@ operation could raise an @isIllegalOperation@, as
described in Section~\ref{IOError}; all other permissible errors are
described below. Note that, in particular, if an implementation does
not support an operation it should raise an @isIllegalOperation@.
A directory contains a series of entries, each of which is a named
reference to a file system object (file, directory etc.). Some
entries may be hidden, inaccessible, or have some administrative
function (for instance, ``.'' or ``..'' under POSIX), but all such
entries are considered to form part of the directory contents.
Entries in sub-directories are not, however, considered to form part
of the directory contents. Although there may be
file system objects other than files and directories, this library
does not distinguish between physical files and other non-directory
objects. All such objects should therefore be treated as if they are files.
Each file system object is referenced by a {\it path}\index{path}. There is
normally at least one absolute path to each file system object. In
some operating systems, it may also be possible to have paths which
are relative to the current directory.
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:
@isPermissionError@ if the user is not permitted to create the directory;
@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
implementation may specify additional constraints which must be
satisfied before a directory can be removed (for instance, the directory has to
be empty, or may not be in use by other processes). It is not legal
for an implementation to partially remove a directory unless the
entire directory is removed. A conformant implementation need not
support directory removal in all situations (for instance, removal of the root
directory).
Computation @removeFile@~"file" removes the directory entry for an existing
file "file", where "file" is not itself a directory\index{deleting
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:
@isPermissionError@ if the user is not permitted to remove the file/directory;
or @isDoesNotExistError@ if the file/directory does not exist.
Computation @renameDirectory@~"old"~"new" changes the name of an existing
directory from "old" to "new"\index{renaming directories}\index{moving
directories}. If the "new" directory already exists, it is atomically
replaced by the "old" directory. If the "new" directory is neither
the "old" directory nor an alias of the "old" directory, it is removed
as if by @removeDirectory@. A conformant implementation need not
support renaming directories in all situations (for instance, renaming to an
existing directory, or across different physical devices), but the
constraints must be documented.
Computation @renameFile@~"old"~"new" changes the name of an existing file
system object from "old" to "new"\index{renaming files}\index{moving files}.
If the "new" object already exists, it is atomically replaced by the "old"
object. Neither path may refer to an existing directory. A conformant
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:
@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:
@isPermissionError@ if the user is not permitted to access the directory;
or @isDoesNotExistError@ if the directory does not exist.
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}.
@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.
The @Permissions@ type is used to record whether certain operations are
permissible on a file/directory. @getPermissions@ and
@setPermissions@ get and set these permissions, respectively.
Permissions apply both to files and directories. For
directories, the @executable@ field will be @False@, and for files the
@searchable@ field will be @False@. Note that directories may be
searchable without being readable, if permission has been given to use
them as part of a path, but not to examine the directory contents.
Note that to change
some, but not all permissions, a construct on the following lines must
be used.
\bprog
@
makeReadable f = do
p <- getPermissions f
setPermissions f (p {readable = True})
@
\eprog
The operation @doesDirectoryExist@ returns @True@ if the argument file
exists and is a directory, and @False@ otherwise. The operation @doesFileExist@ returns @True@
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}.
<