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

Empty log message

parents
# Makefile for the Haskell Library Report
# read the README file before you start!
#
# Begin by saying
# touch library.idx
default: library.ps html
#########################################
# Tools you need
#########################################
# Stuf from the tools/directory
RUN_TEX = ../tools/run_tex
RUN_INDEX = ../tools/run_index
VERBATIM = ../tools/verbatim
# splitAndIndexPgm won't work unless you have "perl"
SPLITPGM = perl ../tools/splitAndIndexPgm
CC = gcc
RM = rm -f
LATEX = latex
MAKEINDEX = makeindex
# 'expand' expands tabs to spaces
# On my machine the windows program (which does something
# quite different) shadows it. Sigh.
EXPAND = expand
#########################################
# Files
#########################################
# I've been having problems with that damn NT messing up filenames in the html
# generator so I'm changing the .verb files to lower case -- jcp
PARTS = library.tex introduction.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
CODE = code/Ratio.tex code/Complex.tex code/Ix.tex \
code/Numeric.tex \
code/Array.tex code/Char.tex code/List.tex \
code/Monad.tex code/Maybe.tex code/IO.tex \
code/Time.tex code/Locale.tex
CODEV = code/Ratio.verb code/Complex.verb code/Ix.verb \
code/Numeric.verb \
code/Array.verb code/Char.verb code/List.verb \
code/Monad.verb code/Maybe.verb code/IO.verb code/Bit.verb \
code/Time.verb code/Locale.verb
HEADERS = headers/Ratio.tex headers/Complex.tex headers/Ix.tex \
headers/Numeric.tex \
headers/Array.tex headers/IO.tex headers/Char.tex \
headers/List.tex headers/List1.tex \
headers/Monad.tex headers/System.tex headers/Directory.tex \
headers/Maybe.tex headers/IO1.tex headers/Random.tex \
headers/Time.tex headers/Time1.tex headers/CPUTime.tex \
headers/Locale.tex
HEADERSV = headers/Ratio.verb headers/Complex.verb headers/Ix.verb \
headers/Numeric.verb \
headers/Array.verb headers/IO.verb headers/Char.verb \
headers/List.verb headers/List1.verb \
headers/Monad.verb headers/System.verb headers/Directory.verb \
headers/Maybe.verb headers/IO1.verb headers/Random.verb \
headers/Time.verb headers/CPUTime.verb \
headers/Locale.verb
# The normally formatted report -- 2 sided, one-up
library.dvi: library.ind ${PARTS} ${CODE} ${HEADERS} index-intro.tex
html: index.html ${PARTS} ${SYNTAX} ${PRELUDE}
-mkdir haskell98-library-html
$(RUN_TEX)
$(RUN_TEX)
cp *.gif index.html haskell98-library-html
# remove this rule if you don't have "makeindex"
library.ind: library.idx
makeindex -i -t library.ilg < library.idx > library.ind
veryclean: clean
$(RM) *~ code/*~ headers/*~
clean:
$(RM) *.dvi *.log *.aux *.ilg *.blg *.toc haskell.tex \
$(PARTS) $(CODE) $(HEADERS) \
library.ps library.pdf haskell98-library-html/*
cp library.ind library.ind.two-sided
echo "Don't delete the Prelude*.tex files"
echo "Not everyone has \"perl\" to re-make them"
# Stuff to make the "two-up" version for SIGPLAN Notices:
# We take the A4 pages and double them up onto (virtual) A3 pages:
# (two A5 pages make one A4 page; two A4 pages make one A3 page; ...)
#
# % dvidvi '2:0,1(210mm,0)' haskell.dvi > haskell-2up.dvi
#
# We now print the "A3" pages in landscape, but "magnify" them by
# 1 / sqrt(2) ~ 0.7071; this should make our "A4" pages print in an
# A4 space: presto! 2up printing!
# (except that I've tried to make it give us 1" margins all round
# when we print on US 8.5"x11" paper)
#
# % dvips -t landscape -x 707 haskell-2up.dvi > haskell-2up.ps
#
# if your "dvips" is set up properly, it will run Metafont for you,
# creating just-right magnifications for all the fonts.
#
# print with: lpr -Pmy-laserwriter haskell-2up.ps
# These rules keep failing for me (segmentation fault on haskell-2up.dvi)
# The output seems fine, though, and the individual commands work
# perfectly(!). More network wierdness? KH
verbs: $(CODEV) $(HEADERSV)
library.ps : library.dvi
dvips library.dvi -o library.ps
publish: library.ps html
gzip < library.ps > y:Haskell/haskell98-library/library.ps.gz
cp haskell98-library-html/* y:Haskell/haskell98-library
tar cvf - haskell98-library-html | gzip > y:Haskell/haskell98-library/haskell98-library-html.tar.gz
publish-pdf: library.pdf
gzip < library.pdf > y:Haskell/haskell98-library/library.pdf.gz
#########################################
# Suffix rules
#########################################
.SUFFIXES: .hs .verb .tex .dvi
.verb.tex:
expand < $< | $(VERBATIM) >$@
.hs.verb:
expand < $< | $(SPLITPGM) >$@
.hs.tex:
expand < $< | $(SPLITPGM) | $(VERBATIM) >$@
.tex.dvi:
$(LATEX) $<
This is the Haskell 98 library report, source distribution.
This has all files needed to generate either the postscript or the
html version of the Haskell library report. Some of these files are
generated from others - these are marked with a (*) and are included in
case the tool used to generate the file is unavailable.
To generate the postscript library report you need lex, perl, latex,
makeindex, and dvips.
To generate the html library report you need Hugs 1.4 (probably any Haskell
1.4 compiler will do).
Source files:
library.verb -- Top level of the library report
introduction.verb
ratio.verb
complex.verb
numeric.verb
ix.verb
array.verb
list.verb
maybe.verb
char.verb
monad.verb
io.verb
directory.verb
system.verb
time.verb
locale.verb
cputime.verb
random.verb
index-intro.verb
Haskell files:
code/*.hs -- executable versions of most libraries (IO incomplete),
-- CPUTime, Random, Directory not included
headers/*.hs -- Lists all exported names from each library
Tex generated files:
library.dvi (*) -- to make a .ps from
library.idx (*)
library.ind (*
library.aux (*) -- The aux file generated by latex; used by html translator
Html support:
tex.hs -- Program to generate html from verb / hs
html.config -- configuration file for tex.hs.
index.html -- Html top level
title.gif -- title graphic
Other files:
Makefile -- Lots of extra cruft no longer used.
verbatim.lex -- lex program to expand .verb into .tex
splitAndIndexPgm -- perl script to convert .hs to .verb
splitAndIndexPgm.kh -- an old perl script to convert .hs to .verb
library.dvi (*) -- in case you just want to run dvips
library.ind (*) -- is case you don't have makeindex
library.idx (*) -- makes building easier
To build the .dvi you need to patch the makefile to call the proper
version of perl. You will have some `non-grokked' instances in the
perl. Remember that you have to run latex twice. If anyone converts
the perl program to perl5 please send it to us! Also, the indexing misses
a few definitions.
Report any problems to peterson-john@cs.yale.edu
Building the HTML files
~~~~~~~~~~~~~~~~~~~~~~~
Build the html by creating a `html' subdirectory, copy the .html and
.gif files to it, and run tex.hs twice (like tex - to get forward refs
right).
Build the html by creating a `html' subdirectory, copy the .html and
.gif files to it, and run tex.hs twice (like tex - to get forward refs
right). Run index.hs to generate the function index. You're done.
The 'make html' does most of this.
There is one file you need to work on:
report/html.config
Edit the title in the headers and footers.
You can hack in whatever html you want for page headers and
footers . You can also hack on the output directory setting (htmldir)
to direct the output wherever you want. You'll have to fiddle
"index.hs" if you do this, though. You can also add the line
style = microsoftsymbols,article
This exploits the symbol font that microsoft uses in its browser.
Much nicer for some of the equations. Probably a good idea since most
browsers handle the symbol font OK nowadays.
As to the building process:
To build the html library report: (using the .aux file and all the .verb files)
cd <library directory>
runhugs tex.hs
runhugs tex.hs
Like latex, you have to run tex.hs twice. Unless you make massive
changes, though, you can probably just do it once. I'm sure ghc will
compile tex.hs if you want to speed things up.
Note there is no index.hs here.
%**<title>The Haskell 98 Library Report: Arrays</title>
%**~header
\section{Arrays}
\label{arrays}
\index{array}
\outline{
\inputHS{headers/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.
Figure~\ref{array-examples} shows some examples that use the
@array@ constructor.
\begin{figure}[tb]
\outline{
@
-- 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
@
}
\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 @map@\indextt{map} 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 @map@ function transforms the array values while
@ixmap@ allows for transformations on array indices.
Figure~\ref{derived-array-examples} shows some examples.
\begin{figure}[tb]
\outline{
@
-- 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,l'),(u,u')) = bounds x
-- Diagonal of a square matrix
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
-- Projection of first components of an array of pairs
firstArray :: (Ix a) => Array a (b,c) -> Array a b
firstArray = map (\(x,y)->x)
@
}
\ecaption{Derived array examples}
\label{derived-array-examples}
\end{figure}
\subsection{Library {\tt Array}}
\label {Libarray}
\inputHS{code/Array}
%**~footer
%**<title>The Haskell 98 Library Report: Character Utilities</title>
%**~header
\section{Character Utilities}
\outline{
\inputHS{headers/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 hexadecmial 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 @readLitChar@ does the reverse.
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{code/Char}
%**~footer
module Array (
module Ix, -- export all of Ix
Array, array, listArray, (!), bounds, indices, elems, assocs,
accumArray, (//), accum, ixmap ) where
import Ix
import List( (\\) )
infixl 9 !, //
data (Ix a) => Array a b = MkArray (a,a) (a -> b) deriving ()
array :: (Ix a) => (a,a) -> [(a,b)] -> Array a b
array b ivs =
if and [inRange b i | (i,_) <- ivs]
then MkArray b
(\j -> case [v | (i,v) <- ivs, i == j] of
[v] -> v
[] -> error "Array.!: \
\undefined array element"
_ -> error "Array.!: \
\multiply defined array element")
else error "Array.array: out-of-range array association"
listArray :: (Ix a) => (a,a) -> [b] -> Array a b
listArray b vs = array b (zipWith (\ a b -> (a,b)) (range b) vs)
(!) :: (Ix a) => Array a b -> a -> b
(!) (MkArray _ f) = f
bounds :: (Ix a) => Array a b -> (a,a)
bounds (MkArray b _) = b
indices :: (Ix a) => Array a b -> [a]
indices = range . bounds
elems :: (Ix a) => Array a b -> [b]
elems a = [a!i | i <- indices a]
assocs :: (Ix a) => Array a b -> [(a,b)]
assocs a = [(i, a!i) | i <- indices a]
(//) :: (Ix a) => Array a b -> [(a,b)] -> Array a b
a // us = array (bounds a)
([(i,a!i) | i <- indices a \\ [i | (i,_) <- us]]
++ us)
accum :: (Ix a) => (b -> c -> b) -> Array a b -> [(a,c)]
-> Array a b
accum f = foldl (\a (i,v) -> a // [(i,f (a!i) v)])
accumArray :: (Ix a) => (b -> c -> b) -> b -> (a,a) -> [(a,c)]
-> Array a b
accumArray f z b = accum f (array b [(i,z) | i <- range b])
ixmap :: (Ix a, Ix b) => (a,a) -> (a -> b) -> Array b c
-> Array a c
ixmap b f a = array b [(i, a ! f i) | i <- range b]
instance (Ix a) => Functor (Array a) where
fmap fn (MkArray b f) = MkArray b (fn . f)
instance (Ix a, Eq b) => Eq (Array a b) where
a == a' = assocs a == assocs a'
instance (Ix a, Ord b) => Ord (Array a b) where
a <= a' = assocs a <= assocs a'
instance (Ix a, Show a, Show b) => Show (Array a b) where
showsPrec p a = showParen (p > 9) (
showString "array " .
shows (bounds a) . showChar ' ' .
shows (assocs a) )
instance (Ix a, Read a, Read b) => Read (Array a b) where
readsPrec p = readParen (p > 9)
(\r -> [(array b as, u) | ("array",s) <- lex r,
(b,t) <- reads s,
(as,u) <- reads t ])
module Char (
isAscii, isLatin1, isControl, isPrint, isSpace, isUpper, isLower,
isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum,
digitToInt, intToDigit,
toUpper, toLower,
ord, chr,
readLitChar, showLitChar, lexLitChar,
-- ...and what the Prelude exports
Char, String
) where
import Array -- used for character name table.