haskell98-report-20080907/0000755000175000017500000000000011345221573014441 5ustar marcotmarcothaskell98-report-20080907/hierarchical-modules/0000755000175000017500000000000011345221572020524 5ustar marcotmarcothaskell98-report-20080907/hierarchical-modules/hier.tex0000644000175000017500000001464311345221572022205 0ustar marcotmarcot% Haskell 98 Addendum: Hierarchical Module Namespace Extension % [ Addendum to the Definition of Haskell 98 ] % % Editor: Simon Marlow % % Copyright 2003 Simon Marlow % % 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 entirety, including this Notice. Modified % versions of this Addendum 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 a definition of The Haskell~98 Hierarchical % Module Namespace Extension. % \documentclass[a4paper,twoside]{article} \usepackage{a4wide} \usepackage{url} \usepackage{code} \newcommand{\clearemptydoublepage}{% \newpage{\pagestyle{empty}\cleardoublepage}} \begin{document} \makeatactive \title{% DRAFT: The Hierarchical Module Namespace Extension, version 0.0\\ An Addendum to the Haskell~98 Report% } \author{ Simon Marlow, Microsoft Research, Cambridge\\ Malcolm Wallace, University of York } \date{} \maketitle \par\vfill \noindent Copyright (c) 2003 Simon Marlow \par\noindent \emph{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 entirety, including this Notice. Modified versions of this Addendum 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 a definition of The Haskell~98 Hierarchical Module Namespace Extension.} \par\bigskip\noindent The master version of Hierarchical Module Namespace Extension is at \url{haskell.org}. Any corrections or changes in the report are found there. \thispagestyle{empty} \clearemptydoublepage \pagenumbering{roman} %\tableofcontents \clearemptydoublepage \section*{Preface} Haskell~98 defines a module system with a \emph{flat} module namespace. That is, module names are just identifiers, and all module names occupy the same namespace. This creates two problems for the Haskell programmer: \begin{itemize} \item There is no consistent naming scheme for modules, so it is hard to locate functionality within a library. \item Module names are likely to clash with each other. It is not possible to choose a module name for a library that is guaranteed not to clash with other library modules. \end{itemize} The purpose of this document is to define a modest extension to Haskell~98 that extends the module namespace and gives it a hierarchical structure. On the face of it, this extension solves neither of the above two problems! However, it is an important first step: in having a way to arrange modules into a hierarchy, we have a \emph{mechanism} to avoid name clashes, and a way to organise libraries into a tree by functionality. The policy by which the hierarchy itself is organised is not in the scope of this specification, but we expect it to be the subject of future specification(s). This document is an \emph{addendum} to the Haskell~98 definition, which means that it has undergone extensive peer-review by the Haskell community prior to publication\footnote{or at least it will have done, by the time version 1.0 is published}. The hierarchical module namespace extension depends on no other Haskell~98 extensions. \subsection*{Acknowledgements} We would like to thank everyone on the mailing list @libraries@\verb+@+@haskell.org@ who has contributed in some way to this proposal, and also those Haskell system implementors who have added this extension to their compilers and interpreters. \clearemptydoublepage \pagenumbering{arabic} \section{The Language Extension} The key concept is to map the module namespace into a hierarchical directory-like structure. We propose using the dot as a separator, analogous to Java's usage for namespaces. This is a surface change to the module naming convention. It does not introduce nested definition of modules. One change is required to the lexical syntax of Haskell, namely that \textit{modid} is redefined from: \[ \textit{modid} \rightarrow \textit{conid} \] \noindent to: \[ \textit{modid} \rightarrow \textit{qconid} \] \noindent for reference, the definition of \textit{qconid} is: \[ \textit{qconid} \rightarrow [ \textit{modid} @.@ ] \textit{conid} \] \noindent Note that the new syntax is recursive, a \textit{modid} may contain multiple components separated by dots, where the final component is a \textit{conid}. A consequence of using the dot as the module namespace separator is that it steals one extremely rare construction from Haskell~98: \begin{code} A.B.C.D \end{code} \noindent in Haskell'98 means the composition of constructor D from module C, with constructor B from module A: \begin{code} (.) A.B C.D \end{code} \noindent With the hierarchical module namespace extension, @A.B.C.D@ would instead be interpreted as the identifier @D@ from module @A.B.C@. If the original Haskell~98 interpretation is intended, then it must be written with extra spaces, as @A.B . C.D@. \section{Modules and the filesystem} This section describes possible implementation techniques, and how we expect the hierarchical namespace to be exposed to the programmer by Haskell implementations. What follows is \emph{not} part of the specification of the hierarchical module namespace extension; Haskell implementations are still free to implement any mapping between modules and filenames they choose (as in plain Haskell~98). For most compilers and interpreters, we expect that the hierarchical module namespace will map directly to a directory/file structure in which the modules are stored. For example, a module @Foo.Bar.Baz@ might be stored in the file @Foo/Bar/Baz.hs@ if @/@ is the directory separator. Note that the hierarchical module namespace is far simpler than a file directory structure, in that hierarchical module names do not provide any operations such as relative paths or parent directory. In the hierarchical module namespace, a particular module name may also be a node in the hierarchy. For example, we might have modules names both @Data.Array@ and @Data.Array.IO@. It is therefore important that directories are distinguished form Haskell source modules, for example by using the @.hs@ suffix: @Data.Array@ would be stored in @Data/Array.hs@ and @Data.Array.IO@ in @Data/Array/IO.hs@. \end{document} haskell98-report-20080907/hierarchical-modules/index.html0000644000175000017500000000327211345221572022525 0ustar marcotmarcot Haskell 98 Hierarchical Module Namespace Extension

Haskell 98 Hierarchical Module Namespace Extension

This is the home of the Hierarchical Module Namespace Extension, an addendum to the Haskell 98 language definition.

Version 0.0 is currently available in the following formats:

System compliance status:

Hierarchical Libraries

The above addendum describes a pure language extension; it makes no attempt to dictate how the namespace should be allocated to libraries, and what module names in the hierarchy are available to programmers.

The following document describes a proposal for the use of the hierarchical module namespace. It is not a Haskell 98 addendum, since it is more policy-oriented. Comments on this document are welcome on the libraries@haskell.org mailing list.

haskell98-report-20080907/hierarchical-modules/Makefile0000644000175000017500000000026711345221572022171 0ustar marcotmarcotall : hier.ps hier.pdf hier.ps: hier.tex TEXINPUTS=../styles: latex $< dvips -f < hier.dvi > $@ hier.pdf: hier.tex TEXINPUTS=../styles: pdflatex $< clean : rm hier.ps hier.pdf haskell98-report-20080907/report/0000755000175000017500000000000011345221573015754 5ustar marcotmarcothaskell98-report-20080907/report/ratio.verb0000644000175000017500000000422111345221573017751 0ustar marcotmarcot%**The Haskell 98 Library Report: Rational Numbers %**~header \section{Rational Numbers} \index{rational numbers} \outline{ \inputHS{lib-hdrs/Ratio} } For each @Integral@ type $t$, there is a type @Ratio@\indextycon{Ratio} $t$ of rational pairs with components of type $t$. The type name @Rational@\indexsynonym{Rational} is a synonym for @Ratio Integer@. @Ratio@ is an instance of classes @Eq@, @Ord@, @Num@, @Real@, @Fractional@, @RealFrac@, @Enum@, @Read@, and @Show@. In each case, the instance for $@Ratio@~t$ simply ``lifts'' the corresponding operations over $t$. If $t$ is a bounded type, the results may be unpredictable; for example @Ratio Int@ may give rise to integer overflow even for rational numbers of small absolute size. The operator @(%)@\index{%@@{\tt {\char'045}}} forms the ratio of two integral numbers, reducing the fraction to terms with no common factor and such that the denominator is positive. The functions @numerator@\indextt{numerator} and @denominator@\indextt{denominator} extract the components of a ratio; these are in reduced form with a positive denominator. @Ratio@ is an abstract type. For example, @12 % 8@ is reduced to 3/2 and @12 % (-8)@ is reduced to (-3)/2. The @approxRational@ function, applied to two real fractional numbers @x@ and @epsilon@, returns the simplest rational number within the open interval "(@x@-@epsilon@, @x@+@epsilon@)". A rational number "n/d" in reduced form is said to be simpler than another "n'/d'" if "|n| \leq |n'|" and "d \leq d'". Note that it can be proved that any real interval contains a unique simplest rational. %% Deleted the following -- this is implementation detail -- KH/AD. % ; here, for simplicity, we assume a closed rational % interval. If such an interval includes at least one whole number, then % the simplest rational is the absolutely least whole number. Otherwise, % the bounds are of the form "q/1 + r/d" and "q/1 + r'/d'", where "|r| < d" % and "|r'| < d'", and the simplest rational is "q/1" + the reciprocal of % the simplest rational between "d'/r'" and "d/r". \clearpage \subsection{Library {\tt Ratio}} \label{Ratio} \inputHS{lib-code/Ratio} %**~footer haskell98-report-20080907/report/literate.verb0000644000175000017500000000533311345221573020451 0ustar marcotmarcot% % $Header: /home/cvs/root/haskell-report/report/literate.verb,v 1.5 2002/12/02 14:53:30 simonpj Exp $ % %**The Haskell 98 Report: Literate Comments %**~header \subsection{Literate comments} \label{literate} \index{literate comments} The ``literate comment'' convention, first developed by Richard Bird and Philip Wadler for Orwell, and inspired in turn by Donald Knuth's ``literate programming'', is an alternative style for encoding \Haskell{} source code. The literate style encourages comments by making them the default. A line in which ``@>@'' is the first character is treated as part of the program; all other lines are comment. The program text is recovered by taking only those lines beginning with ``@>@'', and replacing the leading ``@>@'' with a space. Layout and comments apply exactly as described in Appendix~\ref{syntax} in the resulting text. To capture some cases where one omits an ``@>@'' by mistake, it is an error for a program line to appear adjacent to a non-blank comment line, where a line is taken as blank if it consists only of whitespace. By convention, the style of comment is indicated by the file extension, with ``@.hs@'' indicating a usual Haskell file and ``@.lhs@'' indicating a literate Haskell file. Using this style, a simple factorial program would be: \bprog @ This literate program prompts the user for a number and prints the factorial of that number: > main :: IO () > main = do putStr "Enter a number: " > l <- readLine > putStr "n!= " > print (fact (read l)) This is the factorial function. > fact :: Integer -> Integer > fact 0 = 1 > fact n = n * fact (n-1) @ \eprog An alternative style of literate programming is particularly suitable for use with the LaTeX text processing system. In this convention, only those parts of the literate program that are entirely enclosed between @\begin{code}@$\ldots$@\end{code}@ delimiters are treated as program text; all other lines are comment. More precisely: \begin{itemize} \item Program code begins on the first line following a line that begins @\begin{code}@. \item Program code ends just before a subsequent line that begins @\end{code}@ (ignoring string literals, of course). \end{itemize} It is not necessary to insert additional blank lines before or after these delimiters, though it may be stylistically desirable. For example, \bprog @ \documentstyle{article} \begin{document} \section{Introduction} This is a trivial program that prints the first 20 factorials. \begin{code} main :: IO () main = print [ (n, product [1..n]) | n <- [1..20]] \end{code} \end{document} @ \eprog This style uses the same file extension. It is not advisable to mix these two styles in the same file. %**~footer haskell98-report-20080907/report/maybe.verb0000644000175000017500000000145111345221573017732 0ustar marcotmarcot%**The Haskell 98 Library Report: Maybe Utilities %**~header \section{Maybe Utilities} \outline{ \inputHS{lib-hdrs/Maybe} } The type constructor @Maybe@ is defined in @Prelude@ as \bprog @ data Maybe a = Nothing | Just a @ \eprog The purpose of the @Maybe@ type is to provide a method of dealing with illegal or optional values without terminating the program, as would happen if @error@ were used, and without using @IOError@ from the @IO@ monad, which would cause the expression to become monadic. A correct result is encapsulated by wrapping it in @Just@; an incorrect result is returned as @Nothing@. Other operations on @Maybe@ are provided as part of the monadic classes in the Prelude. \clearpage \subsection{Library {\tt Maybe}} \label {Maybe} \inputHS{lib-code/Maybe} %**~footer haskell98-report-20080907/report/monad.verb0000644000175000017500000001130611345221573017733 0ustar marcotmarcot%**The Haskell 98 Library Report: Monad Utilities %**~header \section{Monad Utilities} \label{Monad} \outline{ \inputHS{lib-hdrs/Monad} } The @Monad@ library defines the @MonadPlus@ class, and provides some useful operations on monads. \subsection{Naming conventions} The functions in this library use the following naming conventions: \begin{itemize} \item A postfix ``@M@'' always stands for a function in the Kleisli category: @m@ is added to function results (modulo currying) and nowhere else. So, for example, \bprog @ filter :: (a -> Bool) -> [a] -> [a] filterM :: Monad m => (a -> m Bool) -> [a] -> m [a] @ \eprog \item A postfix ``@_@'' changes the result type from @(m a)@ to @(m ())@. Thus (in the @Prelude@): \bprog @ sequence :: Monad m => [m a] -> m [a] sequence_ :: Monad m => [m a] -> m () @ \eprog \item A prefix ``@m@'' generalises an existing function to a monadic form. Thus, for example: \bprog @ sum :: Num a => [a] -> a msum :: MonadPlus m => [m a] -> m a @ \eprog \end{itemize} \subsection{Class @MonadPlus@} The @MonadPlus@ class is defined as follows: \bprog @ class Monad m => MonadPlus m where mzero :: m a mplus :: m a -> m a -> m a @ \eprog The class methods @mzero@ and @mplus@ are the zero and plus of the monad. Lists and the @Maybe@ type are instances of @MonadPlus@, thus: \bprog @ instance MonadPlus Maybe where mzero = Nothing Nothing `mplus` ys = ys xs `mplus` ys = xs instance MonadPlus [] where mzero = [] mplus = (++) @ \eprog \subsection{Functions} The @join@ function is the conventional monad join operator. It is used to remove one level of monadic structure, projecting its bound argument into the outer level. % There is no convincing small-scale example for mapAndUnzipM The @mapAndUnzipM@ function maps its first argument over a list, returning the result as a pair of lists. This function is mainly used with complicated data structures or a state-transforming monad. The @zipWithM@ function generalises @zipWith@ to arbitrary monads. For instance the following function displays a file, prefixing each line with its line number, \par {\small \bprog @ listFile :: String -> IO () listFile nm = do cts <- readFile nm zipWithM_ (\i line -> do putStr (show i); putStr ": "; putStrLn line) [1..] (lines cts) @ \eprog } The @foldM@ function is analogous to @foldl@, except that its result is encapsulated in a monad. Note that @foldM@ works from left-to-right over the list arguments. This could be an issue where @(>>)@ and the ``folded function'' are not commutative. \bprog @ foldM f a1 [x1, x2, ..., xm ] == do a2 <- f a1 x1 a3 <- f a2 x2 ... f am xm @ \eprog If right-to-left evaluation is required, the input list should be reversed. % Omitted for now. These functions are very useful in parsing libraries % - but in a slightly modified form: % o It is conventional to return the _longest_ parse first - not % shortest first. % o The function is too strict - you can't get any part of the result % until the entire parse completes. The fix is to use the function % force when defining zeroOrMore. % % force :: Parser a -> Parser a % force (P m) = P (\i -> let x = p i in % (fst (head x), snd (head x)) : tail x) % % but how are we to generalise this to an arbitrary monad? % % The @zeroOrMore@ function performs an action repeatedly - returning % the list of all results obtained. The @oneOrMore@ function is similar % but the action must succeed at least once. That is, % \bprog % % zeroOrMore m = zero ++ % [ [a0] | a0 <- m ] ++ % [ [a0,a1] | a0 <- m, a1 <- m ] ++ % [ [a0,a1,a2] | a0 <- m, a1 <- m, a2 <- m ] ++ % ... % % oneOrMore m = [ [a0] | a0 <- m ] ++ % [ [a0,a1] | a0 <- m, a1 <- m ] ++ % [ [a0,a1,a2] | a0 <- m, a1 <- m, a2 <- m ] ++ % ... % % \eprog The @when@ and @unless@ functions provide conditional execution of monadic expressions. For example, \bprog @ when debug (putStr "Debugging\n") @ \eprog will output the string @"Debugging\n"@ if the Boolean value @debug@ is @True@, and otherwise do nothing. The monadic lifting operators promote a function to a monad. The function arguments are scanned left to right. For example, \bprog @ liftM2 (+) [0,1] [0,2] = [0,2,1,3] liftM2 (+) (Just 1) Nothing = Nothing @ \eprog In many situations, the @liftM@ operations can be replaced by uses of @ap@, which promotes function application. \bprog @ return f `ap` x1 `ap` ... `ap` xn @ \eprog is equivalent to \bprog @ liftMn f x1 x2 ... xn @ \eprog \clearpage \subsection{Library {\tt Monad}} \inputHS{lib-code/Monad} %**~footer haskell98-report-20080907/report/PreludeIO.hs0000644000175000017500000000407111345221573020142 0ustar marcotmarcotmodule PreludeIO ( FilePath, IOError, ioError, userError, catch, putChar, putStr, putStrLn, print, getChar, getLine, getContents, interact, readFile, writeFile, appendFile, readIO, readLn ) where import PreludeBuiltin type FilePath = String data IOError -- The internals of this type are system dependent instance Show IOError where ... instance Eq IOError where ... ioError :: IOError -> IO a ioError = primIOError userError :: String -> IOError userError = primUserError catch :: IO a -> (IOError -> IO a) -> IO a catch = primCatch putChar :: Char -> IO () putChar = primPutChar putStr :: String -> IO () putStr s = mapM_ putChar s putStrLn :: String -> IO () putStrLn s = do putStr s putStr "\n" print :: Show a => a -> IO () print x = putStrLn (show x) getChar :: IO Char getChar = primGetChar getLine :: IO String getLine = do c <- getChar if c == '\n' then return "" else do s <- getLine return (c:s) getContents :: IO String getContents = primGetContents interact :: (String -> String) -> IO () -- The hSetBuffering ensures the expected interactive behaviour interact f = do hSetBuffering stdin NoBuffering hSetBuffering stdout NoBuffering s <- getContents putStr (f s) readFile :: FilePath -> IO String readFile = primReadFile writeFile :: FilePath -> String -> IO () writeFile = primWriteFile appendFile :: FilePath -> String -> IO () appendFile = primAppendFile -- raises an exception instead of an error readIO :: Read a => String -> IO a readIO s = case [x | (x,t) <- reads s, ("","") <- lex t] of [x] -> return x [] -> ioError (userError "Prelude.readIO: no parse") _ -> ioError (userError "Prelude.readIO: ambiguous parse") readLn :: Read a => IO a readLn = do l <- getLine r <- readIO l return r haskell98-report-20080907/report/exps.verb0000644000175000017500000016367411345221573017634 0ustar marcotmarcot% % $Header: /home/cvs/root/haskell-report/report/exps.verb,v 1.20 2003/01/13 13:08:55 simonpj Exp $ % %*section 3 %**The Haskell 98 Report: Expressions %**~header \section{Expressions}\index{expression} \label{expressions} In this chapter, we describe the syntax and informal semantics of \Haskell{} {\em expressions}, including their translations into the \Haskell{} kernel, where appropriate. Except in the case of @let@ expressions, these translations preserve both the static and dynamic semantics. Free variables and constructors used in these translations always refer to entities defined by the @Prelude@. For example, ``@concatMap@'' used in the translation of list comprehensions (Section~\ref{list-comprehensions}) means the @concatMap@ defined by the @Prelude@, regardless of whether or not the identifier ``@concatMap@'' is in scope where the list comprehension is used, and (if it is in scope) what it is bound to. In the syntax that follows, there are some families of nonterminals indexed by precedence levels (written as a superscript). Similarly, the nonterminals "op", "varop", and "conop" may have a double index: a letter "l", "r", or "n" for left-, right- or non-associativity and a precedence level. A precedence-level variable "i" ranges from 0 to 9; an associativity variable "a" varies over "\{l, r, n\}". For example @@@ aexp -> @(@ exp^{i+1} qop^{(a,i)} @)@ @@@ actually stands for 30 productions, with 10 substitutions for "i" and 3 for "a". @@@ exp -> exp^0 @::@ [context @=>@] type & (\tr{expression type signature}) | exp^0 exp^i -> exp^{i+1} [qop^{({\rm{n}},i)} exp^{i+1}] | lexp^i | rexp^i lexp^i -> (lexp^i | exp^{i+1}) qop^{({\rm{l}},i)} exp^{i+1} lexp^6 -> @-@ exp^7 rexp^i -> exp^{i+1} qop^{({\rm{r}},i)} (rexp^i | exp^{i+1}) exp^{10} -> @\@ apat_1 ... apat_n @->@ exp & (\tr{lambda abstraction}, n>=1) | @let@ decls @in@ exp & ({\tr{let expression}}) | @if@ exp @then@ exp @else@ exp & (\tr{conditional}) | @case@ exp @of@ @{@ alts @}@ & (\tr{case expression}) | @do@ @{@ stmts @}@ & (\tr{do expression}) | fexp fexp -> [fexp] aexp & (\tr{function application}) aexp -> qvar & (\tr{variable}) | gcon & (\tr{general constructor}) | literal | @(@ exp @)@ & (\tr{parenthesized expression}) | @(@ exp_1 @,@ ... @,@ exp_k @)@ & (\tr{tuple}, k>=2) | @[@ exp_1 @,@ ... @,@ exp_k @]@ & (\tr{list}, k>=1) | @[@ exp_1 [@,@ exp_2] @..@ [exp_3] @]@ & (\tr{arithmetic sequence}) | @[@ exp @|@ qual_1 @,@ ... @,@ qual_n @]@ & (\tr{list comprehension}, n>=1) | @(@ exp^{i+1} qop^{(a,i)} @)@ & (\tr{left section}) | @(@ lexp^{i} qop^{(l,i)} @)@ & (\tr{left section}) | @(@ qop^{(a,i)}_{\langle@-@\rangle} exp^{i+1} @)@ & (\tr{right section}) | @(@ qop^{(r,i)}_{\langle@-@\rangle} rexp^{i} @)@ & (\tr{right section}) | qcon @{@ fbind_1 @,@ ... @,@ fbind_n @}@ & (\tr{labeled construction}, n>=0) | aexp_{\langle{}qcon\rangle{}} @{@ fbind_1 @,@ ... @,@ fbind_n @}@ & (\tr{labeled update}, n >= 1) @@@ \indexsyn{exp}% \index{exp@@"exp^i"}% \index{lexp@@"lexp^i"}% \index{rexp@@"rexp^i"}% \indexsyn{aexp}% \indexsyn{fexp}% % Removed Aug 2001: more misleading than helpful. SLPJ % As an aid to understanding this grammar, % Table~\ref{syntax-precedences} shows the relative precedence of % expressions, patterns and definitions, plus an extended associativity. % "-" indicates that the item is non-associative. % % \begin{table}[tb] % \[ % \centerline{ % \begin{tabular}{|l|c|}\hline % Item & Associativity \\ % \hline % & \\ % simple terms, parenthesized terms & -- \\ % irrefutable patterns (@~@) & -- \\ % as-patterns ({\tt @@}) & right \\ % function application & left \\ % @do@, @if@, @let@, lambda(@\@), @case@ (leftwards)& right \\ % @case@ (rightwards) & right \\ % & \\ % infix operators, prec. 9 & as defined \\ % \ldots & \ldots \\ % infix operators, prec. 0 & as defined \\ % & \\ % function types (@->@) & right \\ % contexts (@=>@) & -- \\ % type constraints (@::@) & -- \\ % @do@, @if@, @let@, lambda(@\@) (rightwards) & right \\ % sequences (@..@) & -- \\ % generators (@<-@) & -- \\ % grouping (@,@) & n-ary \\ % guards (@|@) & -- \\ % case alternatives (@->@) & -- \\ % definitions (@=@) & -- \\ % separation (@;@) & n-ary \\ % \hline % \end{tabular} % } % \] % %**

Table 1

% \ecaption{Precedence of expressions, patterns, definitions (highest to lowest)} % \label{syntax-precedences} % \end{table} Expressions involving infix operators are disambiguated by the operator's fixity (see Section~\ref{fixity}). Consecutive unparenthesized operators with the same precedence must both be either left or right associative to avoid a syntax error. Given an unparenthesized expression ``"x qop^{(a,i)} y qop^{(b,j)} z"'', parentheses must be added around either ``"x qop^{(a,i)} y"'' or ``"y qop^{(b,j)} z"'' when "i=j" unless "a=b={\rm l}" or "a=b={\rm r}". Negation\index{negation} is the only prefix operator in \Haskell{}; it has the same precedence as the infix @-@ operator defined in the Prelude (see Section~\ref{fixity}, Figure~\ref{prelude-fixities}). The grammar is ambiguous regarding the extent of lambda abstractions, let expressions, and conditionals. The ambiguity is resolved by the meta-rule that each of these constructs extends as far to the right as possible. % I can't make head or tail of this para, so % I'm just deleting it. SLPJ Dec 98 % The separation of function arrows from case alternatives solves % the ambiguity that otherwise arises when an unparenthesized % function type is used in an expression, such as the guard in a case % expression. Sample parses are shown below. \[\bt{|l|l|}%%b \hline This & Parses as \\ \hline @f x + g y@ & @(f x) + (g y)@ \\ @- f x + y@ & @(- (f x)) + y@ \\ @let { ... } in x + y@ & @let { ... } in (x + y)@ \\ @z + let { ... } in x + y@ & @z + (let { ... } in (x + y))@ \\ @f x y :: Int@ & @(f x y) :: Int@ \\ @\ x -> a+b :: Int@ & @\ x -> ((a+b) :: Int@) \\ \hline\et\] {\em A note about parsing.} Expressions that involve the interaction of fixities with the let/lambda meta-rule may be hard to parse. For example, the expression \bprog @ let x = True in x == x == True @ \eprog cannot possibly mean \bprog @ let x = True in (x == x == True) @ \eprog because @(==)@ is a non-associative operator; so the expression must parse thus: \bprog @ (let x = True in (x == x)) == True @ \eprog However, implementations may well use a post-parsing pass to deal with fixities, so they may well incorrectly deliver the former parse. Programmers are advised to avoid constructs whose parsing involves an interaction of (lack of) associativity with the let/lambda meta-rule. For the sake of clarity, the rest of this section shows the syntax of expressions without their precedences. \subsection{Errors} \label{basic-errors}\index{error} Errors during expression evaluation, denoted by "\bot"\index{"\bot"}, are indistinguishable by a Haskell program from non-termination. Since \Haskell{} is a non-strict language, all \Haskell{} types include "\bot". That is, a value of any type may be bound to a computation that, when demanded, results in an error. When evaluated, errors cause immediate program termination and cannot be caught by the user. The Prelude provides two functions to directly cause such errors: \bprog @ error :: String -> a undefined :: a @ \eprog \indextt{error} \indextt{undefined} A call to @error@ terminates execution of the program and returns an appropriate error indication to the operating system. It should also display the string in some system-dependent manner. When @undefined@ is used, the error message is created by the compiler. Translations of \Haskell{} expressions use @error@ and @undefined@ to explicitly indicate where execution time errors may occur. The actual program behavior when an error occurs is up to the implementation. The messages passed to the @error@ function in these translations are only suggestions; implementations may choose to display more or less information when an error occurs. \subsection{Variables, Constructors, Operators, and Literals} \label{vars-and-lits} % @@@ aexp -> qvar & (\tr{variable}) | gcon & (\tr{general constructor}) | literal @@@ \indexsyn{var}% \indexsyn{con}% \indexsyn{varop}% \indexsyn{conop}% \indexsyn{op}% @@@ gcon -> @()@ | @[]@ | @(,@\{@,@\}@)@ | qcon var -> varid | @(@ varsym @)@ & (\tr{variable}) qvar -> qvarid | @(@ qvarsym @)@ & (\tr{qualified variable}) con -> conid | @(@ consym @)@ & (\tr{constructor}) qcon -> qconid | @(@ gconsym @)@ & (\tr{qualified constructor}) varop -> varsym | \bkqB varid \bkqA & (\tr{variable operator}) qvarop -> qvarsym | \bkqB qvarid \bkqA & (\tr{qualified variable operator}) conop -> consym | \bkqB conid \bkqA & (\tr{constructor operator}) qconop -> gconsym | \bkqB qconid \bkqA & (\tr{qualified constructor operator}) op -> varop | conop & (\tr{operator}) qop -> qvarop | qconop & (\tr{qualified operator}) gconsym -> @:@ | qconsym @@@ \indexsyn{gcon}% \indexsyn{var}% \indexsyn{qvar}% \indexsyn{con}% \indexsyn{qcon}% \indexsyn{varop}% \indexsyn{qvarop}% \indexsyn{conop}% \indexsyn{qconop}% \indexsyn{qop}% \indexsyn{gconsym}% \Haskell{} provides special syntax to support infix notation. An {\em operator} is a function that can be applied using infix syntax (Section~\ref{operators}), or partially applied using a {\em section} (Section~\ref{sections}). An {\em operator} is either an {\em operator symbol}, such as @+@ or @$$@, or is an ordinary identifier enclosed in grave accents (backquotes), such as \bkqB@op@\bkqA. For example, instead of writing the prefix application @op x y@, one can write the infix application \mbox{@x@ \bkqB@op@\bkqA@ y@}. If no fixity\index{fixity} declaration is given for \bkqB@op@\bkqA{} then it defaults to highest precedence and left associativity (see Section~\ref{fixity}). Dually, an operator symbol can be converted to an ordinary identifier by enclosing it in parentheses. For example, @(+) x y@ is equivalent to @x + y@, and @foldr (*) 1 xs@ is equivalent to @foldr (\x y -> x*y) 1 xs@. % This para is covered by Section 2.4 and 5.5.1 % A qualified name may only be used to refer to a variable or % constructor imported from another module (see Section~\ref{import}), or % defined at the top level, % but not in the definition of a new variable or constructor. Thus % \bprog % let F.x = 1 in F.x -- invalid % \eprog % incorrectly uses a qualifier in the definition of @x@, regardless of % the module containing this definition. Qualification does not affect % the nature of an operator: @F.+@ is an infix operator just as @+@ is. Special syntax is used to name some constructors for some of the built-in types, as found in the production for "gcon" and "literal". These are described in Section~\ref{basic-types}. \index{number!translation of literals} An integer literal represents the application of the function @fromInteger@\indextt{fromInteger} to the appropriate value of type @Integer@. Similarly, a floating point literal stands for an application of @fromRational@\indextt{fromRational} to a value of type @Rational@ (that is, @Ratio Integer@). \outline{ \paragraph*{Translation:} The integer literal "i" is equivalent to @fromInteger@ "i", where @fromInteger@ is a method in class @Num@ (see Section \ref{numeric-literals}).\indexclass{Num} The floating point literal "f" is equivalent to @fromRational@ ("n" @Ratio.%@ "d"), where @fromRational@ is a method in class @Fractional@ and @Ratio.%@ constructs a rational from two integers, as defined in the @Ratio@ library.\indexclass{Fractional} The integers "n" and "d" are chosen so that "n/d = f". } \subsection{Curried Applications and Lambda Abstractions} \label{applications} \label{lambda-abstractions} \index{lambda abstraction} \index{application} %\index{function application|see{application}} % @@@ fexp -> [fexp] aexp & (\tr{function application}) exp -> @\@ apat_1 ... apat_n @->@ exp & (\tr{lambda abstraction}, n>=1) @@@ \indexsyn{exp}% \indexsyn{fexp}% \noindent {\em Function application}\index{application} is written "e_1 e_2". Application associates to the left, so the parentheses may be omitted in @(f x) y@. Because "e_1" could be a data constructor, partial applications of data constructors are allowed. {\em Lambda abstractions} are written "@\@ p_1 ... p_n @->@ e", where the "p_i" are {\em patterns}. An expression such as @\x:xs->x@ is syntactically incorrect; it may legally be written as @\(x:xs)->x@. The set of patterns must be {\em linear}\index{linearity}% \index{linear pattern}---no variable may appear more than once in the set. \outline{\small \paragraph*{Translation:} The following identity holds: \begin{center} \bt{lcl}% \struthack{17pt}% "@\@ p_1 ... p_n @->@ e" & "=" & "@\@ x_1 ... x_n @-> case (@x_1@,@ ...@,@ x_n@) of (@p_1@,@ ...@,@ p_n@) ->@ e" \et \end{center} where the "x_i" are new identifiers. } Given this translation combined with the semantics of case expressions and pattern matching described in Section~\ref{case-semantics}, if the pattern fails to match, then the result is "\bot". \subsection{Operator Applications} \index{operator application} %\index{operator application|hseealso{application}} \label{operators} % @@@ exp -> exp_1 qop exp_2 | @-@ exp & (\tr{prefix negation}) qop -> qvarop | qconop & (\tr{qualified operator}) @@@ \indexsyn{exp}% \indexsyn{qop}% \noindent The form "e_1 qop e_2" is the infix application of binary operator\index{operator} "qop" to expressions "e_1" and "e_2". The special form "@-@e" denotes prefix negation\index{negation}, the only prefix operator in \Haskell{}, and is syntax for "@negate @(e)".\indextt{negate} The binary @-@ operator does not necessarily refer to the definition of @-@ in the Prelude; it may be rebound by the module system. However, unary @-@ will always refer to the @negate@ function defined in the Prelude. There is no link between the local meaning of the @-@ operator and unary negation. Prefix negation has the same precedence as the infix operator @-@ defined in the Prelude (see Table~\ref{prelude-fixities}% %*ignore , page~\pageref{prelude-fixities}% %*endignore ). Because @e1-e2@ parses as an infix application of the binary operator @-@, one must write @e1(-e2)@ for the alternative parsing. Similarly, @(-)@ is syntax for @(\ x y -> x-y)@, as with any infix operator, and does not denote @(\ x -> -x)@---one must use @negate@ for that. \outline{ \paragraph*{Translation:} The following identities hold: \begin{center} \bt{lcl}% \struthack{17pt}% "e_1 op e_2" & "=" & "@(@op@)@ e_1 e_2" \\ "@-@e" & "=" & "@negate@ (e)" \et \end{center} } \subsection{Sections} \index{section} %\index{section|hseealso{operator application}} \label{sections} % @@@ aexp -> @(@ exp^{i+1} qop^{(a,i)} @)@ & (\tr{left section}) | @(@ lexp^{i} qop^{(l,i)} @)@ & (\tr{left section}) | @(@ qop^{(a,i)}_{\langle@-@\rangle} exp^{i+1} @)@ & (\tr{right section}) | @(@ qop^{(r,i)}_{\langle@-@\rangle} rexp^{i} @)@ & (\tr{right section}) @@@ \indexsyn{aexp}% \noindent {\em Sections} are written as "@(@ op e @)@" or "@(@ e op @)@", where "op" is a binary operator and "e" is an expression. Sections are a convenient syntax for partial application of binary operators. Syntactic precedence rules apply to sections as follows. "@(@op~e@)@" is legal if and only if "@(x@~op~e@)@" parses in the same way as "@(x@~op~@(@e@))@"; and similarly for "@(@e~op@)@". For example, @(*a+b)@ is syntactically invalid, but @(+a*b)@ and @(*(a+b))@ are valid. Because @(+)@ is left associative, @(a+b+)@ is syntactically correct, but @(+a+b)@ is not; the latter may legally be written as @(+(a+b))@. As another example, the expression \bprog @ (let n = 10 in n +) @ \eprog is invalid because, by the let/lambda meta-rule (Section~\ref{expressions}), the expression \bprog @ (let n = 10 in n + x) @ \eprog parses as \bprog @ (let n = 10 in (n + x)) @ \eprog rather than \bprog @ ((let n = 10 in n) + x) @ \eprog % This observation makes it easier to implement the let/lambda meta-rule % (Section~\ref{expressions}) because once the operator has been seen it is clear that any % legal parse must include the operator in the body of the @let@. Because @-@ is treated specially in the grammar, "@(-@ exp@)@" is not a section, but an application of prefix negation,\index{negation} as described in the preceding section. However, there is a @subtract@ function defined in the Prelude such that "@(subtract@ exp@)@" is equivalent to the disallowed section. The expression "@(+ (-@ exp@))@" can serve the same purpose. % Changed to allow postfix operators. That is, in (op x), we no % longer add a \x -> which would require op to be binary instead % of unary. \outline{ \paragraph*{Translation:} The following identities hold: \begin{center} \bt{lcl}% \struthack{17pt}% "@(@op e@)@" & "=" & "@\@ x @->@ x op e" \\ "@(@e op@)@" & "=" & "@\@ x @->@ e op x" \et \end{center} where "op" is a binary operator, "e" is an expression, and "x" is a variable that does not occur free in "e". } \subsection{Conditionals} \label{conditionals}\index{conditional expression} % @@@ exp -> @if@ exp_1 @then@ exp_2 @else@ exp_3 @@@ \indexsyn{exp}% %\indextt{if ... then ... else ...} A {\em conditional expression} \index{conditional expression} has the form "@if@ e_1 @then@ e_2 @else@ e_3" and returns the value of "e_2" if the value of "e_1" is @True@, "e_3" if "e_1" is @False@, and "\bot" otherwise. \outline{ \paragraph*{Translation:} The following identity holds: \begin{center} \bt{lcl}% \struthack{17pt}% "@if@ e_1 @then@ e_2 @else@ e_3" & "=" & "@case@ e_1 @of { True ->@ e_2 @; False ->@ e_3 @}@" \et \end{center} where @True@ and @False@ are the two nullary constructors from the type @Bool@, as defined in the Prelude. The type of "e_1" must be @Bool@; "e_2" and "e_3" must have the same type, which is also the type of the entire conditional expression. } \subsection{Lists} \label{lists} % @@@ exp -> exp_1 qop exp_2 aexp -> @[@ exp_1 @,@ ... @,@ exp_k @]@ & (k>=1) | gcon gcon -> @[]@ | qcon qcon -> @(@ gconsym @)@ qop -> qconop qconop -> gconsym gconsym -> @:@ @@@ \indexsyn{aexp}% {\em Lists}\index{list} are written "@[@e_1@,@ ...@,@ e_k@]@", where "k>=1". The list constructor is @:@, and the empty list is denoted @[]@. Standard operations on lists are given in the Prelude (see Section~\ref{basic-lists}, and Chapter~\ref{stdprelude} notably Section~\ref{preludelist}). \outline{ \paragraph*{Translation:} The following identity holds: \begin{center} \bt{lcl}% \struthack{17pt}% "@[@e_1@,@ ...@,@ e_k@]@" & "=" & "e_1 @: (@e_2 @: (@ ... @(@e_k @: [])))@" \et \end{center} where @:@ and @[]@ are constructors for lists, as defined in the Prelude (see Section~\ref{basic-lists}). The types of "e_1" through "e_k" must all be the same (call it "t\/"), and the type of the overall expression is @[@"t"@]@ (see Section~\ref{type-syntax}). } The constructor ``@:@'' is reserved solely for list construction; like @[]@, it is considered part of the language syntax, and cannot be hidden or redefined. It is a right-associative operator, with precedence level 5 (Section~\ref{fixity}). \subsection{Tuples} \label{tuples} % @@@ aexp -> @(@ exp_1 @,@ ... @,@ exp_k @)@ & (k>=2) | qcon qcon -> @(,@\{@,@\}@)@ @@@ \indexsyn{aexp}% {\em Tuples}\index{tuple} are written "@(@e_1@,@ ...@,@ e_k@)@", and may be of arbitrary length "k>=2". The constructor for an "n"-tuple is denoted by @(,@\ldots@,)@, where there are "n-1" commas. Thus @(a,b,c)@ and @(,,) a b c@ denote the same value. Standard operations on tuples are given in the Prelude (see Section~\ref{basic-tuples} and Chapter~\ref{stdprelude}). \outline{ \paragraph*{Translation:} "@(@e_1@,@ ...@,@ e_k@)@" for "k\geq2" is an instance of a "k"-tuple as defined in the Prelude, and requires no translation. If "t_1" through "t_k" are the types of "e_1" through "e_k", respectively, then the type of the resulting tuple is "@(@t_1@,@ ...@,@ t_k@)@" (see Section~\ref{type-syntax}). } \subsection{Unit Expressions and Parenthesized Expressions} \label{unit-expression} \index{unit expression} % @@@ aexp -> gcon | @(@ exp @)@ gcon -> @()@ @@@ \indexsyn{aexp}% \noindent The form "@(@e@)@" is simply a {\em parenthesized expression}, and is equivalent to "e". The {\em unit expression} @()@ has type @()@\index{trivial type} (see Section~\ref{type-syntax}). It is the only member of that type apart from $\bot$, and can be thought of as the ``nullary tuple'' (see Section~\ref{basic-trivial}). \nopagebreak[4] \outline{ \paragraph{Translation:} "@(@e@)@" is equivalent to "e". } \subsection{Arithmetic Sequences} \label{arithmetic-sequences} % @@@ aexp -> @[@ exp_1 [@,@ exp_2] @..@ [exp_3] @]@ @@@ \indexsyn{aexp}% \noindent The {\em arithmetic sequence}\index{arithmetic sequence} "@[@e_1@,@ e_2 @..@ e_3@]@" denotes a list of values of type "t", where each of the "e_i" has type "t", and "t" is an instance of class @Enum@. \outline{ \paragraph{Translation:} Arithmetic sequences satisfy these identities: \begin{center} \begin{tabular}{lcl}% \struthack{17pt}% @[ @"e_1"@.. ]@ & "=" & @enumFrom@ "e_1" \\ @[ @"e_1"@,@"e_2"@.. ]@ & "=" & @enumFromThen@ "e_1" "e_2" \\ @[ @"e_1"@..@"e_3"@ ]@ & "=" & @enumFromTo@ "e_1" "e_3" \\ @[ @"e_1"@,@"e_2"@..@"e_3"@ ]@ & "=" & @enumFromThenTo@ "e_1" "e_2" "e_3" \end{tabular} \end{center} where @enumFrom@, @enumFromThen@, @enumFromTo@, and @enumFromThenTo@ are class methods in the class @Enum@ as defined in the Prelude (see Figure~\ref{standard-classes}% %*ignore , page~\pageref{standard-classes}% %*endignore ). } The semantics of arithmetic sequences therefore depends entirely on the instance declaration for the type "t". See Section~\ref{enum-class} for more details of which @Prelude@ types are in @Enum@ and their semantics. \subsection{List Comprehensions} \index{list comprehension} \index{let expression!in list comprehensions} \label{list-comprehensions} % @@@ aexp -> @[@ exp @|@ qual_1 @,@ ... @,@ qual_n @]@ & (\tr{list comprehension}, n>=1) qual -> pat @<-@ exp & (\tr{generator}) | @let@ decls & (\tr{local declaration}) | exp & (\tr{guard}) @@@ \indexsyn{aexp} \indexsyn{qual} \noindent A {\em list comprehension} has the form "@[@ e @|@ q_1@,@ ...@,@ q_n @]@, n>=1," where the "q_i" qualifiers\index{qualifier} are either \begin{itemize} \item {\em generators}\index{generator} of the form "p @<-@ e", where "p" is a pattern (see Section~\ref{pattern-matching}) of type "t" and "e" is an expression of type "@[@t@]@" \item {\em guards},\index{guard} which are arbitrary expressions of type @Bool@ \item {\em local bindings} that provide new definitions for use in the generated expression "e" or subsequent guards and generators. \end{itemize} Such a list comprehension returns the list of elements produced by evaluating "e" in the successive environments created by the nested, depth-first evaluation of the generators in the qualifier list. Binding of variables occurs according to the normal pattern matching rules (see Section~\ref{pattern-matching}), and if a match fails then that element of the list is simply skipped over. Thus:\nopagebreak[4] \bprog @ [ x | xs <- [ [(1,2),(3,4)], [(5,4),(3,2)] ], (3,x) <- xs ] @ \eprog yields the list @[4,2]@. If a qualifier is a guard, it must evaluate to @True@ for the previous pattern match to succeed. As usual, bindings in list comprehensions can shadow those in outer scopes; for example: \[\ba{lll} @[ x | x <- x, x <- x ]@ & = & @[ z | y <- x, z <- y]@ \\ \ea\] \outline{ \paragraph{Translation:} List comprehensions satisfy these identities, which may be used as a translation into the kernel: \begin{center} \bt{lcl}% \struthack{17pt}% "@[ @ e@ | True ]@" & = & "@[@e@]@" \\ "@[ @ e@ | @q@ ]@" & = & "@[@~ e~@|@~q@, True ]@" \\ "@[ @ e@ | @b@,@~ Q ~@]@" & = & "@if@~b~@then@~@[ @ e@ | @Q@ ]@~@else []@" \\ "@[ @ e@ | @p @<-@ l@,@~ Q@ ]@" & = & "@let ok@~p~@=@~@[ @ e@ | @Q@ ]@" \\ && @ ok _ = []@ \\ && "@in concatMap ok@~ l" \\ "@[ @ e@ | let@~decls@,@~ Q@ ]@" & = & "@let@~decls~@in@~@[ @ e@ | @Q@ ]@" \et \end{center} where "e" ranges over expressions, "p" over patterns, "l" over list-valued expressions, "b" over boolean expressions, "decls" over declaration lists, "q" over qualifiers, and "Q" over sequences of qualifiers. "@ok@" is a fresh variable. The function @concatMap@, and boolean value @True@, are defined in the Prelude. } As indicated by the translation of list comprehensions, variables bound by @let@ have fully polymorphic types while those defined by @<-@ are lambda bound and are thus monomorphic (see Section \ref{monomorphism}). \subsection{Let Expressions} \index{let expression} \label{let-expressions} % % Including this syntax blurb does REALLY bad things to page breaking % in the 1.[12] report (sigh); ToDo: hope it goes away. @@@ exp -> @let@ decls @in@ exp @@@ \indexsyn{exp} \index{declaration!within a {\tt let} expression} \noindent {\em Let expressions} have the general form "@let {@ d_1 @;@ ... @;@ d_n @} in@ e", and introduce a nested, lexically-scoped, mutually-recursive list of declarations (@let@ is often called @letrec@ in other languages). The scope of the declarations is the expression "e" and the right hand side of the declarations. Declarations are described in Chapter~\ref{declarations}. Pattern bindings are matched lazily; an implicit @~@ makes these patterns irrefutable.\index{irrefutable pattern} For example, \bprog @ let (x,y) = undefined in @"e"@ @ \eprog does not cause an execution-time error until @x@ or @y@ is evaluated. \outline{\small \paragraph*{Translation:} The dynamic semantics of the expression "@let {@ d_1 @;@ ... @;@ d_n @} in@ e_0" are captured by this translation: After removing all type signatures, each declaration "d_i" is translated into an equation of the form "p_i @=@ e_i", where "p_i" and "e_i" are patterns and expressions respectively, using the translation in Section~\ref{function-bindings}. Once done, these identities hold, which may be used as a translation into the kernel: \begin{center} \bt{lcl}% \struthack{17pt}% @let {@"p_1"@=@"e_1"@; @ ... @; @"p_n"@=@"e_n"@} in@ "e_0" &=& @let (~@"p_1"@,@ ... @,~@"p_n"@) = (@"e_1"@,@ ... @,@"e_n"@) in@ "e_0" \\ @let @"p"@ = @"e_1" @ in @ "e_0" &=& @case @"e_1"@ of ~@"p"@ -> @"e_0" \\ & & {\rm where no variable in "p" appears free in "e_1"} \\ @let @"p"@ = @"e_1" @ in @ "e_0" &=& @let @"p"@ = fix ( \ ~@"p"@ -> @"e_1"@) in@ "e_0" \et \end{center} where @fix@ is the least fixpoint operator. Note the use of the irrefutable patterns "@~@p". This translation does not preserve the static semantics because the use of @case@ precludes a fully polymorphic typing of the bound variables. %\folks{Needs work -- KH} % This same semantics applies to the top-level of %a program that has been translated into a @let@ expression, % as described at the beginning of Section~\ref{modules}. The static semantics of the bindings in a @let@ expression are described in Section~\ref{pattern-bindings}. } \subsection{Case Expressions} \label{case} % @@@ exp -> @case@ exp @of@ @{@ alts @}@ alts -> alt_1 @;@ ... @;@ alt_n & (n>=1) alt -> pat @->@ exp [@where@ decls] | pat gdpat [@where@ decls] | & (empty alternative) gdpat -> gd @->@ exp [ gdpat ] gd -> @|@ exp^0 @@@ \indexsyn{exp}% \indexsyn{alts}% \indexsyn{alt}% \indexsyn{gdpat}% \indexsyn{gd}% A {\em case expression}\index{case expression} has the general form \[ "@case@ e @of { @p_1 match_1 @;@ ... @;@ p_n match_n @}@" \] where each "match_i" is of the general form \[\ba{lll} & "@|@ g_{i1}" & "@->@ e_{i1}" \\ & "..." \\ & "@|@ g_{im_i}" & "@->@ e_{im_i}" \\ & \multicolumn{2}{l}{"@where@ decls_i"} \ea\] (Notice that in the syntax rule for "gd", the ``@|@'' is a terminal symbol, not the syntactic metasymbol for alternation.) Each alternative "p_i match_i" consists of a pattern\index{pattern} "p_i" and its matches, "match_i". Each match in turn consists of a sequence of pairs of guards\index{guard} "g_{ij}" and bodies "e_{ij}" (expressions), followed by optional bindings ("decls_i") that scope over all of the guards and expressions of the alternative. An alternative of the form \[ "pat @->@ exp @where@ decls" \] is treated as shorthand for: \[\ba{lll} & "pat @| True@" & "@->@ exp" \\ & \multicolumn{2}{l}{"@where@ decls"} \ea\] A case expression must have at least one alternative and each alternative must have at least one body. Each body must have the same type, and the type of the whole expression is that type. A case expression is evaluated by pattern matching the expression "e" against the individual alternatives. The alternatives are tried sequentially, from top to bottom. If "e" matches the pattern in the alternative, the guards for that alternative are tried sequentially from top to bottom, in the environment of the case expression extended first by the bindings created during the matching of the pattern, and then by the "decls_i" in the @where@ clause associated with that alternative. If one of the guards evaluates to @True@, the corresponding right-hand side is evaluated in the same environment as the guard. If all the guards evaluate to @False@, matching continues with the next alternative. If no match succeeds, the result is "\bot". Pattern matching is described in Section~\ref{pattern-matching}, with the formal semantics of case expressions in Section~\ref{case-semantics}. {\em A note about parsing.} The expression \bprog @ case x of { (a,_) | let b = not a in b :: Bool -> a } @ \eprog is tricky to parse correctly. It has a single unambiguous parse, namely \bprog @ case x of { (a,_) | (let b = not a in b :: Bool) -> a } @ \eprog However, the phrase "@Bool -> a@" is syntactically valid as a type, and parsers with limited lookahead may incorrectly commit to this choice, and hence reject the program. Programmers are advised, therefore, to avoid guards that end with a type signature --- indeed that is why a "gd" contains an "exp^0" not an "exp". \subsection{Do Expressions} \index{do expression} \label{do-expressions} \index{let expression!in do expressions} \index{monad} % @@@ exp -> @do@ @{@ stmts @}@ & (\tr{do expression}) stmts -> stmt_1 ... stmt_n exp [@;@] & (n>=0) stmt -> exp @;@ | pat @<-@ exp @;@ | @let@ decls @;@ | @;@ & (empty statement) @@@ % The semicolons are done differently than for decls % Reason: to do it the same way would mean: % stmts -> stmt1 ; ... ; stmtn ; exp [;] % Now, what happens if n=0? Is there a ';' before the exp or not? % Putting the ';' on the end of the stmt makes that clear. \indexsyn{exp}% \indexsyn{stmt}% \indexsyn{stmts}% A {\em do expression} provides a more conventional syntax for monadic programming. It allows an expression such as \bprog @ putStr "x: " >> getLine >>= \l -> return (words l) @ \eprog to be written in a more traditional way as: \bprog @ do putStr "x: " l <- getLine return (words l) @ \eprog \outline{ \paragraph*{Translation:} Do expressions satisfy these identities, which may be used as a translation into the kernel, after eliminating empty "stmts": \begin{center} \bt{lcl}% \struthack{17pt}% @do {@"e"@}@ &=& "e"\\ @do {@"e"@;@"stmts"@}@ &=& "e" @>> do {@"stmts"@}@ \\ @do {@"p"@ <- @"e"@; @"stmts"@}@ &=& @let ok @"p"@ = do {@"stmts"@}@\\ & & @ ok _ = fail "..."@\\ & & @ in @"e"@ >>= ok@ \\ @do {let@ "decls"@; @"stmts"@}@ &=& @let@ "decls" @in do {@"stmts"@}@\\ \et \end{center} The ellipsis @"..."@ stands for a compiler-generated error message, passed to @fail@, preferably giving some indication of the location of the pattern-match failure; the functions @>>@, @>>=@, and @fail@ are operations in the class @Monad@, as defined in the Prelude\indexclass{Monad}; and @ok@ is a fresh identifier. } As indicated by the translation of @do@, variables bound by @let@ have fully polymorphic types while those defined by @<-@ are lambda bound and are thus monomorphic. \subsection{Datatypes with Field Labels} \label{field-ops} \index{data declaration@@{\tt data} declaration} \index{label} \index{field label|see{label}} A datatype declaration may optionally define field labels (see Section~\ref{datatype-decls}). These field labels can be used to construct, select from, and update fields in a manner that is independent of the overall structure of the datatype. Different datatypes cannot share common field labels in the same scope. A field label can be used at most once in a constructor. Within a datatype, however, a field label can be used in more than one constructor provided the field has the same typing in all constructors. To illustrate the last point, consider: \bprog @ data S = S1 { x :: Int } | S2 { x :: Int } -- OK data T = T1 { y :: Int } | T2 { y :: Bool } -- BAD @ \eprog Here @S@ is legal but @T@ is not, because @y@ is given inconsistent typings in the latter. \subsubsection{Field Selection} @@@ aexp -> qvar @@@ \index{field label!selection} Field labels are used as selector functions. When used as a variable, a field label serves as a function that extracts the field from an object. Selectors are top level bindings and so they may be shadowed by local variables but cannot conflict with other top level bindings of the same name. This shadowing only affects selector functions; in record construction (Section~\ref{record-construction}) and update (Section~\ref{record-update}), field labels cannot be confused with ordinary variables. \outline{ \paragraph*{Translation:} A field label "f" introduces a selector function defined as: \begin{center} \bt{lcl} \struthack{17pt}% "f"@ x@ &=&@case x of {@ "C_1 p_{11} \ldots p_{1k}" @ -> @ "e_1" @;@ "\ldots" @;@ "C_n p_{n1} \ldots p_{nk}" @ -> @ "e_n" @}@\\ \et \end{center} where "C_1 \ldots C_n" are all the constructors of the datatype containing a field labeled with "f", "p_{ij}" is @y@ when "f" labels the "j"th component of "C_i" or @_@ otherwise, and "e_i" is @y@ when some field in "C_i" has a label of "f" or @undefined@ otherwise. } \subsubsection{Construction Using Field Labels} \label{record-construction} \index{field label!construction} @@@ aexp -> qcon @{@ fbind_1 @,@ ... @,@ fbind_n @}@ & (\tr{labeled construction}, n>=0) fbind -> qvar @=@ exp @@@ \indexsyn{fbind}% A constructor with labeled fields may be used to construct a value in which the components are specified by name rather than by position. Unlike the braces used in declaration lists, these are not subject to layout; the @{@ and @}@ characters must be explicit. (This is also true of field updates and field patterns.) Construction using field labels is subject to the following constraints: \begin{itemize} \item Only field labels declared with the specified constructor may be mentioned. \item A field label may not be mentioned more than once. \item Fields not mentioned are initialized to $\bot$. \item A compile-time error occurs when any strict fields (fields whose declared types are prefixed by @!@) are omitted during construction. Strict fields are discussed in Section~\ref{strictness-flags}. \end{itemize} The expression @F {}@, where @F@ is a data constructor, is legal {\em whether or not @F@ was declared with record syntax} (provided @F@ has no strict fields --- see the third bullet above); it denotes "@F@ \bot_1 ... \bot_n", where "n" is the arity of @F@. \outline{ \paragraph*{Translation:} In the binding "f" @=@ "v", the field "f" labels "v". \begin{center} \bt{lcl} \struthack{17pt}% "C" @{@ "bs" @}@ &=& "C (pick^C_1 bs @undefined@) \ldots (pick^C_k bs @undefined@)"\\ \et \end{center} where "k" is the arity of "C". The auxiliary function "pick^C_i bs d" is defined as follows: \begin{quote} If the "i"th component of a constructor "C" has the field label "f", and if "f=v" appears in the binding list "bs", then "pick^C_i bs d" is "v". Otherwise, "pick^C_i bs d" is the default value "d". \end{quote} } \subsubsection{Updates Using Field Labels} \label{record-update} \index{field label!update} @@@ aexp -> aexp_{\langle{}qcon\rangle{}} @{@ fbind_1 @,@ ... @,@ fbind_n @}@ & (\tr{labeled update}, n>=1) @@@ Values belonging to a datatype with field labels may be non-destructively updated. This creates a new value in which the specified field values replace those in the existing value. Updates are restricted in the following ways: \begin{itemize} \item All labels must be taken from the same datatype. \item At least one constructor must define all of the labels mentioned in the update. \item No label may be mentioned more than once. \item An execution error occurs when the value being updated does not contain all of the specified labels. \end{itemize} \outline{ \paragraph*{Translation:} Using the prior definition of "pick", \begin{center} \bt{lcl} \struthack{17pt}% "e" @{@ "bs" @}@ &=& @case@ "e" @of@\\ &&@ @"C_1 v_1 ... v_{k_1}" @->@ "C_1 (pick^{C_1}_1 bs v_1) ... (pick^{C_1}_{k_1} bs v_{k_1})"\\ &&@ @ ... \\ &&@ @"C_j v_1 ... v_{k_j}" @->@ "C_j (pick^{C_j}_1 bs v_1) ... (pick^{C_j}_{k_j} bs v_{k_j})"\\ &&@ _ -> error "Update error"@\\ \et \end{center} where "\{C_1,...,C_j\}" is the set of constructors containing all labels in "bs", and "k_i" is the arity of "C_i". } Here are some examples using labeled fields: \bprog @ data T = C1 {f1,f2 :: Int} | C2 {f1 :: Int, f3,f4 :: Char} @ \eprog \[\bt{|l|l|}%%b \hline Expression & Translation \\ \hline @C1 {f1 = 3}@ & @C1 3 undefined@ \\ @C2 {f1 = 1, f4 = 'A', f3 = 'B'}@ & @C2 1 'B' 'A'@ \\ @x {f1 = 1}@ & @case x of C1 _ f2 -> C1 1 f2@ \\ & @ C2 _ f3 f4 -> C2 1 f3 f4@ \\ \hline\et\] The field @f1@ is common to both constructors in T. This example translates expressions using constructors in field-label notation into equivalent expressions using the same constructors without field labels. A compile-time error will result if no single constructor defines the set of field labels used in an update, such as @x {f2 = 1, f3 = 'x'}@. \subsection{Expression Type-Signatures} \index{expression type-signature} \label{expression-type-sigs} % @@@ exp -> exp @::@ [context @=>@] type @@@ \indexsyn{exp} \indextt{::} \nopagebreak[4] {\em Expression type-signatures} have the form "e @::@ t", where "e" is an expression and "t" is a type (Section~\ref{type-syntax}); they are used to type an expression explicitly and may be used to resolve ambiguous typings due to overloading (see Section~\ref{default-decls}). The value of the expression is just that of "exp". As with normal type signatures (see Section~\ref{type-signatures}), the declared type may be more specific than the principal type derivable from "exp", but it is an error to give a type that is more general than, or not comparable to, the principal type. \outline{ \paragraph*{Translation:} \begin{center} \bt{lcl} \struthack{17pt}% "e @::@ t" & = & "@let {@ v @::@ t@; @ v @=@ e @} in @v" \et \end{center} } \subsection{Pattern Matching} \index{pattern-matching} \label{pattern-matching} \label{patterns} {\em Patterns} appear in lambda abstractions, function definitions, pattern bindings, list comprehensions, do expressions, and case expressions. However, the first five of these ultimately translate into case expressions, so defining the semantics of pattern matching for case expressions is sufficient. %it suffices to restrict the definition of the semantics of %pattern-matching to case expressions. \subsubsection{Patterns} \label{pattern-definitions} Patterns\index{pattern} have this syntax: @@@ pat -> var @+@ integer & (\tr{successor pattern}) | pat^0 pat^i -> pat^{i+1} [qconop^{({\rm{n}},i)} pat^{i+1}] | lpat^i | rpat^i lpat^i -> (lpat^i | pat^{i+1}) qconop^{({\rm{l}},i)} pat^{i+1} lpat^6 -> @-@ (integer | float) & (\tr{negative literal}) rpat^i -> pat^{i+1} qconop^{({\rm{r}},i)} (rpat^i | pat^{i+1}) pat^{10} -> apat | gcon apat_1 ... apat_k & (\tr{arity} gcon = k, k>=1) apat -> var [{\tt @@} apat] & (\tr{as pattern}) | gcon & (\tr{arity} gcon = 0) | qcon @{@ fpat_1 @,@ ... @,@ fpat_k @}@ & (\tr{labeled pattern}, k>=0) | literal | @_@ & (\tr{wildcard}) | @(@ pat @)@ & (\tr{parenthesized pattern}) | @(@ pat_1 @,@ ... @,@ pat_k @)@ & (\tr{tuple pattern}, k>=2) | @[@ pat_1 @,@ ... @,@ pat_k @]@ & (\tr{list pattern}, k>=1) | @~@ apat & (\tr{irrefutable pattern}) fpat -> qvar @=@ pat @@@ \indexsyn{pat}% \index{pat@@"pat^i"}% \index{lpat@@"lpat^i"}% \index{rpat@@"rpat^i"}% \indexsyn{apat}% \indexsyn{fpats}% \indexsyn{fpat}% The arity of a constructor must match the number of sub-patterns associated with it; one cannot match against a partially-applied constructor. All patterns must be {\em linear}\index{linearity} \index{linear pattern}---no variable may appear more than once. For example, this definition is illegal: @ f (x,x) = x -- ILLEGAL; x used twice in pattern @ Patterns of the form "var"{\tt @@}"pat" are called {\em as-patterns}, \index{as-pattern ({\tt {\char'100}})} and allow one to use "var" as a name for the value being matched by "pat". For example,\nopagebreak[4] \bprog @ case e of { xs@@(x:rest) -> if x==0 then rest else xs } @ \eprog is equivalent to: \bprog @ let { xs = e } in case xs of { (x:rest) -> if x==0 then rest else xs } @ \eprog Patterns of the form @_@ are {\em wildcards}\index{wildcard pattern ({\tt {\char'137}})} and are useful when some part of a pattern is not referenced on the right-hand-side. It is as if an identifier not used elsewhere were put in its place. For example, \bprog @ case e of { [x,_,_] -> if x==0 then True else False } @ \eprog is equivalent to: \bprog @ case e of { [x,y,z] -> if x==0 then True else False } @ \eprog % where @y@ and @z@ are identifiers not used elsewhere. %old: %This translation is also %assumed prior to the semantics given below. \subsubsection{Informal Semantics of Pattern Matching} Patterns are matched against values. Attempting to match a pattern can have one of three results: it may {\em fail\/}; it may {\em succeed}, returning a binding for each variable in the pattern; or it may {\em diverge} (i.e.~return "\bot"). Pattern matching proceeds from left to right, and outside to inside, according to the following rules: \begin{enumerate} \item Matching the pattern "var" against a value "v" always succeeds and binds "var" to "v". \item Matching the pattern "@~@apat" against a value "v" always succeeds. The free variables in "apat" are bound to the appropriate values if matching "apat" against "v" would otherwise succeed, and to "\bot" if matching "apat" against "v" fails or diverges. (Binding does {\em not} imply evaluation.) Operationally, this means that no matching is done on a "@~@apat" pattern until one of the variables in "apat" is used. At that point the entire pattern is matched against the value, and if the match fails or diverges, so does the overall computation. \item Matching the wildcard pattern @_@ against any value always succeeds, and no binding is done. \item Matching the pattern "con pat" against a value, where "con" is a constructor defined by @newtype@, depends on the value: \begin{itemize} \item If the value is of the form "con v", then "pat" is matched against "v". \item If the value is "\bot", then "pat" is matched against "\bot". \end{itemize} That is, constructors associated with @newtype@ serve only to change the type of a value.\index{newtype declaration@@{\tt newtype} declaration} \item Matching the pattern "con pat_1 \ldots pat_n" against a value, where "con" is a constructor defined by @data@, depends on the value: \begin{itemize} \item If the value is of the form "con v_1 \ldots v_n", sub-patterns are matched left-to-right against the components of the data value; if all matches succeed, the overall match succeeds; the first to fail or diverge causes the overall match to fail or diverge, respectively. \item If the value is of the form "con' v_1 \ldots v_m", where "con" is a different constructor to "con'", the match fails. \item If the value is "\bot", the match diverges. \end{itemize} \item Matching against a constructor using labeled fields is the same as matching ordinary constructor patterns except that the fields are matched in the order they are named in the field list. All fields listed must be declared by the constructor; fields may not be named more than once. Fields not named by the pattern are ignored (matched against @_@). \item Matching a numeric, character, or string literal pattern "k" against a value "v" \index{literal pattern} succeeds if "v ~@==@ ~k", where @==@ is overloaded based on the type of the pattern. The match diverges if this test diverges. The interpretation of numeric literals is exactly as described in Section~\ref{vars-and-lits}; that is, the overloaded function @fromInteger@ or @fromRational@ is applied to an @Integer@ or @Rational@ literal (resp) to convert it to the appropriate type. \item Matching an "n@+@k" pattern (where "n" is a variable and "k" is a positive integer literal) against a value "v" \index{n+k pattern@@"n@+@k" pattern} succeeds if "v ~@>=@ ~k", resulting in the binding of "n" to "v~@-@~k", and fails otherwise. Again, the functions @>=@ and @-@ are overloaded, depending on the type of the pattern. The match diverges if the comparison diverges. The interpretation of the literal "k" is the same as in numeric literal patterns, except that only integer literals are allowed. \item Matching an as-pattern "var"{\tt @@}"apat" against a value "v" is \index{as-pattern ({\tt {\char'100}})} the result of matching "apat" against "v", augmented with the binding of "var" to "v". If the match of "apat" against "v" fails or diverges, then so does the overall match. \end{enumerate} Aside from the obvious static type constraints (for example, it is a static error to match a character against a boolean), the following static class constraints hold: \begin{itemize} \item An integer literal pattern \index{integer literal pattern} can only be matched against a value in the class @Num@. \item A floating literal pattern \index{floating literal pattern} can only be matched against a value in the class @Fractional@. \item An "n@+@k" pattern \index{n+k pattern@@"n@+@k" pattern} can only be matched against a value in the class @Integral@. \end{itemize} Many people feel that "n@+@k" patterns should not be used. These patterns may be removed or changed in future versions of \Haskell{}. It is sometimes helpful to distinguish two kinds of patterns. Matching an {\em irrefutable pattern} \index{irrefutable pattern} is non-strict: the pattern matches even if the value to be matched is "\bot". Matching a {\em refutable} pattern is strict: if the value to be matched \index{refutable pattern} is "\bot" the match diverges. The irrefutable patterns are as follows: a variable, a wildcard, "N apat" where "N" is a constructor defined by @newtype@ and "apat" is irrefutable (see Section~\ref{datatype-renaming}), \index{newtype declaration@@{\tt newtype} declaration} "var"{\tt @@}"apat" where "apat" is irrefutable, or of the form "@~@apat" (whether or not "apat" is irrefutable). All other patterns are {\em refutable}. Here are some examples: \begin{enumerate} \item If the pattern @['a','b']@ is matched against "@['x',@\bot@]@", then @'a'@ "fails" to match against @'x'@, and the result is a failed match. But if @['a','b']@ is matched against "@[@\bot@,'x']@", then attempting to match @'a'@ against "\bot" causes the match to "diverge". \item These examples demonstrate refutable vs.~irrefutable matching: \bprog @ (\ ~(x,y) -> 0) @"\bot"@ @"\Rightarrow"@ 0 (\ (x,y) -> 0) @"\bot"@ @"\Rightarrow"@ @"\bot"@ @ \eprog \bprog @ (\ ~[x] -> 0) [] @"\Rightarrow"@ 0 (\ ~[x] -> x) [] @"\Rightarrow"@ @"\bot"@ @ \eprog \bprog @ (\ ~[x,~(a,b)] -> x) [(0,1),@"\bot"@] @"\Rightarrow"@ (0,1) (\ ~[x, (a,b)] -> x) [(0,1),@"\bot"@] @"\Rightarrow"@ @"\bot"@ @ \eprog \bprog @ (\ (x:xs) -> x:x:xs) @"\bot"@ @"\Rightarrow"@ @"\bot"@ (\ ~(x:xs) -> x:x:xs) @"\bot"@ @"\Rightarrow"@ @"\bot"@:@"\bot"@:@"\bot"@ @ \eprogNoSkip \item Consider the following declarations: \bprog @ newtype N = N Bool data D = D !Bool @ \eprog These examples illustrate the difference in pattern matching between types defined by @data@ and @newtype@: \bprog @ (\ (N True) -> True) @"\bot"@ @"\Rightarrow"@ @"\bot"@ (\ (D True) -> True) @"\bot"@ @"\Rightarrow"@ @"\bot"@ (\ ~(D True) -> True) @"\bot"@ @"\Rightarrow"@ True @ \eprog Additional examples may be found in Section~\ref{datatype-renaming}. \end{enumerate} \nopagebreak[4] % \bprog % @@ % (\ t -> let (x,y) = t in 0) @@"\bot"@@ @@"\Rightarrow"@@ 0 % (\ (x,y) -> 0) @@"\bot"@@ @@"\Rightarrow"@@ @@"\bot"@@ % @@ % \eprog % \bprog % @@ % (\ l -> let [x] = l in 0) [] @@"\Rightarrow"@@ 0 % (\ l -> let [x] = l in x) [] @@"\Rightarrow"@@ @@"\bot"@@ % @@ % \eprog % \bprog % @@ % (\ l -> let [x,t] = l; (a,b) = t in x) [(0,1),@@"\bot"@@] @@"\Rightarrow"@@ (0,1) % (\ l -> let [x, (a,b)] = l in x) [(0,1),@@"\bot"@@] @@"\Rightarrow"@@ @@"\bot"@@ % @@ % \eprog % \bprog % @@ % (\ (x:xs) -> x:x:xs) @@"\bot"@@ @@"\Rightarrow"@@ @@"\bot"@@ % (\ l -> let (x:xs) = l in x:x:xs) @@"\bot"@@ @@"\Rightarrow"@@ @@"\bot"@@:@@"\bot"@@:@@"\bot"@@ % @@ % \eprogNoSkip % \end{enumerate} Top level patterns in case expressions and the set of top level patterns in function or pattern bindings may have zero or more associated {\em guards}\index{guard}. A guard is a boolean expression that is evaluated only after all of the arguments have been successfully matched, and it must be true for the overall pattern match to succeed. The environment of the guard is the same as the right-hand-side of the case-expression alternative, function definition, or pattern binding to which it is attached. The guard semantics have an obvious influence on the strictness characteristics of a function or case expression. In particular, an otherwise irrefutable pattern \index{irrefutable pattern} may be evaluated because of a guard. For example, in \bprog @ f :: (Int,Int,Int) -> [Int] -> Int f ~(x,y,z) [a] | (a == y) = 1 @ \eprog % \bprog % @@ % f t [a] | a==y = 1 % where (x,y,z) = t % @@ % \eprog both @a@ and @y@ will be evaluated by @==@ in the guard. \subsubsection{Formal Semantics of Pattern Matching} \label{case-semantics} The semantics of all pattern matching constructs other than @case@ expressions are defined by giving identities that relate those constructs to @case@ expressions. The semantics of @case@ expressions themselves are in turn given as a series of identities, in Figures~\ref{simple-case-expr-1}--\ref{simple-case-expr-2}. Any implementation should behave so that these identities hold; it is not expected that it will use them directly, since that would generate rather inefficient code. \begin{figure}[tb] \outlinec{\small \begin{tabular}{@@{}cl} (a)&@case @$e$@ of { @$alts$@ } @$=$@ (\@$v$@ -> case @$v$@ of { @$alts$@ }) @"e"\\ &{\rm where $v$ is a new variable}\\ (b)&@case @$v$@ of { @$p_1\ \ match_1$@; @$\ldots{}$@ ; @$p_n\ \ match_n$@ }@\\ &$=$@ case @$v$@ of { @$p_1\ \ match_1$@ ;@\\ &@ _ -> @$\ldots{}$@ case @$v$@ of {@\\ &@ @$p_n\ \ match_n$\ @;@\\ &@ _ -> error "No match" }@$\ldots$@}@\\ &@ @{\rm where each $match_i$ has the form:}\\ &@ | @$g_{i,1}$ @ -> @$e_{i,1}$@ ; @$\ldots{}$@ ; | @$g_{i,m_i}$@ -> @$e_{i,m_i}$@ where { @$decls_i$@ }@\\[4pt] %\\ (c)&@case @$v$@ of { @$p$@ | @$g_1$@ -> @$e_1$@ ; @$\ldots{}$\\ &\hspace*{4pt}@ | @$g_n$@ -> @$e_n$@ where { @$decls$@ }@\\ &\hspace*{2pt}@ _ -> @$e'$@ }@\\ &$=$@ case @$e'$@ of@\\ & @ {@$y$@ -> @ {\rm (where "y" is a new variable)}\\ &@ case @$v$@ of {@\\ &@ @$p$@ -> let { @$decls$@ } in@\\ &@ if @$g_1$@ then @$e_1$@ @$\ldots{}$@ else if @$g_n$@ then @$e_n$@ else @$y$ \ @;@\\ &@ _ -> @$y$@ }}@\\[4pt] %\\ (d)&@case @$v$@ of { ~@$p$@ -> @$e$@; _ -> @$e'$@ }@\\ &$=$@ (\@$x_1$ $\ldots$ $x_n$ @->@ $e$ @) (case @$v$@ of { @$p$@->@ $x_1$@ })@ $\ldots$ @(case @$v$@ of { @$p$@ -> @$x_n$@})@\\ &{\rm where $x_1, \ldots, x_n$ are all the variables in $p\/$}\\[4pt] %\\ (e)&@case @$v$@ of { @$x${\tt @@}$p$@ -> @$e$@; _ -> @$e'$@ }@\\ &$=$@ case @$v$@ of { @$p$@ -> ( \ @$x$@ -> @$e$@ ) @$v$@ ; _ -> @$e'$@ }@\\[4pt] %\\ (f)&@case @$v$@ of { _ -> @$e$@; _ -> @$e'$@ } @$=$@ @$e$\\[4pt] \end{tabular} } %**

Figure 3

\ecaption{Semantics of Case Expressions, Part 1} \label{simple-case-expr-1} \end{figure} \begin{figure}[tb] \outlinec{\small \begin{tabular}{@@{}cl} (g)&@case @$v$@ of { @$K\ p_1 \ldots p_n$@ -> @$e$@; _ -> @$e'$@ }@\\ &$=$@ case @$v$@ of {@\\ &@ @$K\ x_1 \ldots x_n$@ -> case @$x_1$@ of {@\\ &@ @$p_1$@ -> @$\ldots$@ case @$x_n$@ of { @$p_n$@ -> @$e$@ ; _ -> @$e'$@ } @$\ldots$\\ &@ _ -> @$e'$@ }@\\ &@ _ -> @$e'$@ }@\\[2pt] &{\rm at least one of $p_1, \ldots, p_n$ is not a variable; $x_1, \ldots, x_n$ are new variables}\\[4pt] %\\ (h)&@case @$v$@ of { @$k$@ -> @$e$@; _ -> @$e'$@ } @$=$@ if (@$v$@==@$k$@) then @$e$@ else @$e'$ \\ &{\rm where $k$ is a numeric, character, or string literal.} \\[4pt] %\\ (i)&@case @$v$@ of { @$x$@ -> @$e$@; _ -> @$e'$@ } @$=$@ case @$v$@ of { @$x$@ -> @$e$@ }@\\[4pt] %\\ (j)&@case @$v$@ of { @$x$@ -> @$e$@ } @$=$@ ( \ @$x$@ -> @$e$@ ) @$v$\\[4pt] %\\ (k)&@case @$N$ $v$@ of { @$N$@ @$p$@ -> @$e$@; _ -> @$e'$@ }@\\ &$=$@ case @$v$@ of { @$p$@ -> @$e$@; _ -> @$e'$@ }@\\ &{\rm where $N$ is a @newtype@ constructor}\\[4pt] (l)&@case @$\bot$@ of { @$N$@ @$p$@ -> @$e$@; _ -> @$e'$@ } @$=$@ case @$\bot$@ of { @$p$@ -> @$e$@ }@\\ &{\rm where $N$ is a @newtype@ constructor}\\[4pt] (m)& @case @ $v$ @ of { @ $K$ @ {@ $f_1$ @ = @ $p_1$ @ , @ $f_2$ @ = @ $p_2$ @ , @ $\ldots$ @} -> @ $e$ @; _ -> @ $e'$ @ }@\\ &$=$ @ case @$e'$@ of {@\\ &@ @$y$@ ->@\\ &@ case @ $v$ @ of { @\\ &@ @ $K$ @ { @ $f_1$ @ = @ $p_1$ @ } ->@\\ &@ case @ $v$ @ of {@ $K$ @ {@ $f_2$ @ = @ $p_2$ @ , @ $\ldots$ @ } -> @ $e$ @; _ -> @ $y$ @ };@\\ &@ _ -> @ $y$ @ }}@\\ &{\rm where $f_1$, $f_2$, $\ldots$ are fields of constructor $K$; $y$ is a new variable}\\[4pt] (n)&@case @ $v$ @ of { @ $K$ @ {@ $f$ @ = @ $p$ @} -> @ $e$ @; _ -> @ $e'$ @ }@ \\ &$=$@ case @ $v$ @ of {@\\ & @ @ $K$ $p_1\ \ldots \ p_n$ @ -> @ $e$ @; _ -> @ $e'$ @ }@\\ &{\rm where $p_i$ is $p$ if $f$ labels the $i$th component of $K$, @_@ otherwise}\\ (o)&@case @ $v$ @ of { @ $K$ @ {} -> @ $e$ @; _ -> @ $e'$ @ }@ \\ &$=$@ case @ $v$ @ of {@\\ & @ @ $K$ @_@ $\ldots$ @_ -> @ $e$ @; _ -> @ $e'$ @ }@\\ (p)&@case (@$K'$@ @$e_1$@ @$\ldots$@ @$e_m$@) of { @$K$@ @$x_1$@ @$\ldots$@ @$x_n$@ -> @$e$@; _ -> @$e'$@ } @$=$@ @$e'$\\ &{\rm where $K$ and $K'$ are distinct @data@ constructors of arity $n$ and $m$, respectively}\\[4pt] %\\ (q)&@case (@$K$@ @$e_1$@ @$\ldots$@ @$e_n$@) of { @$K$@ @$x_1$@ @$\ldots$@ @$x_n$@ -> @$e$@; _ -> @$e'$@ }@\\ &$=$@ (\@$x_1~\ldots~x_n$@ -> @$e$@) @$e_1~\ldots~e_n$\\ &{\rm where $K$ is a @data@ constructor of arity $n$}\\[4pt] (r)&@case@~$\bot$~@of { @$K$@ @$x_1$@ @$\ldots$@ @$x_n$@ -> @$e$@; _ -> @$e'$@ }@ ~$=$~ $\bot$ \\ &{\rm where $K$ is a @data@ constructor of arity $n$}\\[4pt] (s)&@case @$v$@ of { @$x$@+@$k$@ -> @$e$@; _ -> @$e'$@ }@\\ &$=$@ if @$v$@ >= @$k$@ then (\@$x$@ -> @$e$@) (@$v$@-@$k$@) else @$e'$\\ &{\rm where $k$ is a numeric literal}\\ \end{tabular} } %**

Figure 4

\ecaption{Semantics of Case Expressions, Part 2} \label{simple-case-expr-2} \end{figure} In Figures~\ref{simple-case-expr-1}--\ref{simple-case-expr-2}: "e", "e'" and "e_i" are expressions; "g" and "g_i" are boolean-valued expressions; "p" and "p_i" are patterns; "v", "x", and "x_i" are variables; "K" and "K'" are algebraic datatype (@data@) constructors (including tuple constructors); and "N" is a @newtype@ constructor\index{newtype declaration@@{\tt newtype} declaration}. % For clarity, several rules are expressed using % @let@ (used only in a non-recursive way); their usual purpose is to % prevent name capture % (e.g., in rule~(c)). The rules may be re-expressed entirely with % @cases@ by applying this identity: % \[ % "@let @x@ = @y@ in @e@ @ =@ case @y@ of { @x@ -> @e@ }@" % \] %Using all but the last two identities (rules~(n) and~(o)) in Figure~\ref{simple-case-expr-2} %in a left-to-right manner yields a translation into a %subset of general @case@ expressions called {\em simple case expressions}.% %\index{simple case expression} Rule~(b) matches a general source-language @case@ expression, regardless of whether it actually includes guards---if no guards are written, then @True@ is substituted for the guards "g_{i,j}" in the "match_i" forms. Subsequent identities manipulate the resulting @case@ expression into simpler and simpler forms. %The semantics of simple @case@ expressions is %given by the last two identities ((n) and~(o)). Rule~(h) in Figure~\ref{simple-case-expr-2} involves the overloaded operator @==@; it is this rule that defines the meaning of pattern matching against overloaded constants. \index{pattern-matching!overloaded constant} %% When used as a translation, the identities in %% Figure~\ref{simple-case-expr} will generate a very inefficient %% program. This can be fixed by using further @case@ or @let@ %% expressions, but doing so %% would clutter the identities, which are intended only to convey the semantics. These identities all preserve the static semantics. Rules~(d),~(e), (j), (q), and~(s) use a lambda rather than a @let@; this indicates that variables bound by @case@ are monomorphically typed (Section~\ref{type-semantics}). \index{monomorphic type variable} %**~footer % Local Variables: % mode: latex % End: haskell98-report-20080907/report/h98.ppt0000644000175000017500000007300011345221573017111 0ustar marcotmarcotÐÏࡱá>þÿ þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿ(þÿÿÿ ) !þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿþÿÿÿ+,-./0123456789þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot Entry0¼w˜xÿÿÿÿÿÿÿÿd›Oφꪹ)èP‡‘>á¾Picturest DocumentPbDf<0¼wÿÿÿÿÿÿÿÿ€?@0¼w PowerPoint DocumentˆØUðô8(ÿÿÿÿÿÿÿÿINNT40\and*|SummaryInformationrmation(ÿÿÿÿ!  !"#$%&'()*+þÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿjklmnopqrsþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ F𺠘îNû§²ÝaR­A€ ÇGÿØÿàJFIFKKÿãMSO Palette àÂ’ãͨäÉæÒ±çѪéΡé×·êÕ¯ëÒ£ëÓ­ë×±ìØ·ìÚ¹íݾîÖ«îÚ¸îܸïÙ¯ïݹïßÀñݵñß¾ñâÀñãÆò߸òáÀôã¾ôäÅôçÊõçÄöêËøîÐÛ¹…ÝÂ—ÝÆ Þ¿ŒÞɧàÈ áÆšáÌ«âʦâÌ¥âέãÉäÃ‰äÆ˜äΧäΫäаåÊŸåÌ åΣåϬåЫåÒ±åÓ³æÆŒæÉ”æÑ«æÓ²çÊçͤçϨçЩçÓ­èÌŸè͘èΤèФèЪèѪèÒ°èÓ©èÔ°èÔ´èÕ±èÖµèÖ¸è×·éÉ’éΠéϧéÔ³éÕ®éÕ±é×±éÚ¹êПêÐ¥êÑ«êÒ¥êÒ«êÓ¥êÓ®êÔ¬êÕ©êÕ²êÖ¶ê×¶êØ²êØ·ëΖëÓ¬ëÔ²ëײë×·ëÙ¶ëÙ¹ëÚ¸ëÚ¹ëÚ»ëÜ¿ìÒ¦ìÔ«ìÕªìÕ®ìÕ±ìÖµì×­ì×²ìØ¯ìÙ²ìÚ¶ìÚ»ìÛ·ìÜ»ìÝ¿íÑíÔ¦íÕ¯íØ·íÛ¼íܸíܺíܾîÓŸîÖªîÖ®î׫î×°îÙ¯îÙ²îÙ¶îÚ¶îÚºîÛ·îÜ´îÜ»îܾîÝ·îÝ»îÞÁîß¾îßÂîàÂïÖ ïÖ§ïÙªïÙ±ïÚ²ïÚ·ïÜ´ïܾïÝ·ïݾïÞ¸ïÞ»ïߺïß½ïßÁïàÁðÚ®ðÛ¸ðܵðܸðݽðÞ¾ðà½ðàÀðâÀðâÆñܲñÞºñ߸ñߺñß½ñßÀñßÁñàºñà¾ñáÀñáÃñâÅñã½ñãÀñãÂñäÆñäÇòÚ¨òÜ­òܹòݵòß½òâ½òâÁòâÅòãÂòäÇòåÆòæËóß²óß¶óà¸óàºóà¾óáÂóâÁóãÄóäÇóåÄóåÇóæÆóæÈóèËôâ¸ôâ¾ôãÁôä½ôäÁôæÂôçÄôçËôêÎõãÄõåÆõæÈõéÈõéËõêÎõìÐöæÀöæÅöçÂöçÉöèÆöèÊöìÌöîÑ÷éÅ÷éÉ÷êÍøìÊøìÐùîÐùðÓúó×ÿÛC   ")$+*($''-2@7-0=0''8L9=CEHIH+6OUNFT@GHEÿÛC !!E.'.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEÿÀ€€"ÿÄÿÄ0!1AQ"aq¡2‘±#ÁÑáCRrðñÿÄÿÄ1AÿÚ ?ô%÷~êìc¦¨ß“ŒFD){|`­Ôô‡Œàt™U¶þ)Ãþ%lŽn¼`÷ *ûc’RÚœ"lBºwo|=ßnëx&ÉIŽ`»~‡s-“¼—šâÞ®ORvÊ´ŸoÒŽûùñŠ®y/ßž1¼™húdz×OyU/&9÷srjð2+›¿œÂ޽ÛãÆEb*õ&ÿ£+îê¯LÓçYÃíO8cêTTðòåF‰¾Oïì¾xÃ/SÝÃ\ MT«ã¶.Ae¯|HCÖ<ïš§ƒj Ë}ñ£Kk¯.±š ýøÌFR×`¥^˜öé=´™êÚ×(`’óßjíD/Ó Úïï“dƯMÞ]ÕÆ$¶CIù±è¾|àiw)x¬Y;#)Úíãñ™Vé—vl¼¶ƒ{‰ã2çEüxÆ”©ê<^Tmvúb‘©[ãxCƒ»ñ ÊÂ*Š?ÞX‰J1bvyÆ=9^¥+ïxI,d[¼7öÉ?òÈ5ûoº`eªÍb&ï^«kë–ŒÙdKþ~¹®ÑŽ«¿ÇÓ­:»oÅb3÷6P4k'¥.Š©5\¸gûßúáýD$=µ€c-Q]Ç(XÇG|ëˆXê𨧶¸Í/PõzÀ4î÷‡Ò )ãÿ˜:¯GÎÎØÌ“÷5z£_VA+SÅ`½|½°J•on¼ëNKúwÌú«ÂÔŒ¸är½U¨xíœð’Å­v/¾S®˜Ä7Å™PzäPÕ>9ÿœÀþûœ듺5¼4 ’À”›«æ“q²2.®œn†õ¯—xç¦~ï—Rƒ( &%h¯Û›¦R—ÆRP€WM&‡ "?´ûâ9 î¥MÇí‘u߯3q85Û F]´|o`¬ûëkÎûíjÞ^øº«~ÙE:þq':X_ç(¿8 m眈”o—¾hv-SÓ„Cç·Æ#­™ õ:MvÊú^§êDIiÿý?" ddÏÿÿïÿÿÿÿÿÿ£|ÿý?" ddMÏÿÿïÿÿÿÿÿÿ € ¨h €" Ï € k7€»ÒŸ £nÿý?" dd@ÿÿïÿÿÿÿÿÿ   @@``€€P£R  h Ï 7 Ÿ`£ p£>  €£>  Ãð»ððSð( ðõõõõõõõõõõõõõõõõ ððð ð ã ðT€4|–€‚K@ƒ–€„K@‡¿ƒ¿Àÿ ðWÇ“ úðà  ðTŸ¨ Click to edit Master title style¢!ª !ð4 ð Ó ðN€Ô{–€‚K@ƒ–€„K@¿ƒ¿Àÿ ðÇ“ fðà  ðžŸ¨RClick to edit Master text styles Second level Third level Fourth level Fifth level¢!    ª Sðñ ð Ó ðN€t{–€‚K@ƒ–€„K@¿ƒ¿Àÿ ð|Çï½ðà  ð[Ÿ¨*¡ø¦ñÏhhÏÏ77ŸŸðó ð Ó ðN€{–€‚K@ƒ–€„K@¿ƒ¿Àÿ ð|‰Ñ½ðà   ð]Ÿ¨*¡ú¦ñÏhhÏÏ77ŸŸðó ð Ó ðN€´z–€‚K@ƒ–€„K@¿ƒ¿Àÿ ð|k“ ½ðà  ð]Ÿ¨*¡Ø¦ñÏhhÏÏ77ŸŸðH ð ƒ ð0ƒ“éI@”ÁÏ¿ÿ ?ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²² º,Blank Presentation.potî6ï€ æðÞ ððvð( ð   ðð>" ð C ðŽ€x–€‚K@ƒ–€„K@…‡¿€ÿÿ̆A‡Á¿Àÿ¨)¨)?¿StationeryðZ Ó ð€Ÿ¨ Haskell 98¡"  ,ª¦ñÏhhÏÏ77ŸŸðH ð ƒ ð0ƒ“éI@”ÁÏ¿ÿ ?ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²²r0#Ä õpþÿÕÍÕœ.“—+,ù®DÕÍÕœ.“—+,ù®Àˆ ¬´¼Ä Ì ÔÜ äìôü  ^äCustom st|è Times New Roman Arial BlackBlank Presentation.potNo Slide Title  Fonts Usedþÿà…ŸòùOh«‘+'³Ù0`! hpˆ¤ð  8 D P\däNo Slide TitleSimon Peyton JonesCC:\Program Files\Microsoft Office\Templates\Blank Presentation.potSimon Peyton Jonesc2moMicrosoft PowerPointoso@€Þh@>à¾@_ˆ>á¾Gôÿÿÿÿo4 òA&ÿÿÿÿºô &ÿÿÿÿ&#ÿÿÿÿTNPPpð0D z & TNPPô &ÿÿÿÿ&TNPP   ôº ÿÿÿ AA Ì* ôº( *@€€€€€€€€€ÀÀÀÀÜÀðʦ """)))UUUMMMBBB999€|ÿPPÿ“ÖÿìÌÆÖïÖçç©­3f™Ì3333f3™3Ì3ÿff3fff™fÌfÿ™™3™f™™™Ì™ÿÌÌ3ÌfÌ™ÌÌÌÿÿfÿ™ÿÌ3333f3™3Ì3ÿ3333333f33™33Ì33ÿ3f3f33ff3f™3fÌ3fÿ3™3™33™f3™™3™Ì3™ÿ3Ì3Ì33Ìf3Ì™3ÌÌ3Ìÿ3ÿ33ÿf3ÿ™3ÿÌ3ÿÿff3fff™fÌfÿf3f33f3ff3™f3Ìf3ÿffff3fffff™ffÌf™f™3f™ff™™f™Ìf™ÿfÌfÌ3fÌ™fÌÌfÌÿfÿfÿ3fÿ™fÿÌÌÿÿÌ™™™3™™™™Ì™™33™f™3Ì™ÿ™f™f3™3f™f™™fÌ™3ÿ™™3™™f™™™™™Ì™™ÿ™Ì™Ì3fÌf™Ì™™ÌÌ™Ìÿ™ÿ™ÿ3™Ìf™ÿ™™ÿÌ™ÿÿÌ™3ÌfÌ™ÌÌ™3Ì33Ì3fÌ3™Ì3ÌÌ3ÿÌfÌf3™ffÌf™ÌfÌ™fÿ̙̙3Ì™fÌ™™Ì™ÌÌ™ÿÌÌÌÌ3ÌÌfÌÌ™ÌÌÌÌÌÿÌÿÌÿ3™ÿfÌÿ™ÌÿÌÌÿÿÌ3ÿfÿ™Ì3ÿ33ÿ3fÿ3™ÿ3Ìÿ3ÿÿfÿf3Ìffÿf™ÿfÌÌfÿÿ™ÿ™3ÿ™fÿ™™ÿ™Ìÿ™ÿÿÌÿÌ3ÿÌfÿÌ™ÿÌÌÿÌÿÿÿ3Ìÿfÿÿ™ÿÿÌffÿfÿffÿÿÿffÿfÿÿÿf!¥___www†††–––ËË˲²²×××ÝÝÝãããêêêñññøøøðûÿ¤  €€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøÿÿÿÿÿÿÿÿÿÿÿÿøøøøÿÿÿÿÿÿÿÿÿÿšÂ½š¼ ½Ã™½™Ã½Ã¼šÃš¼Ã ½š¼ ¼š½Â½™š¼½ ¼š¼ ¼š½Ãš½™Ã½Ÿ½¼Ã½Ã™ÃšÂ½š¼ ½Ã™½™Ã½Ã¼šÃš¼Ã ½š¼ ¼š½Â½™š¼½ ¼š¼ ¼š½Ãš½™Ã½Ÿ½¼Ã½Ã™ÃšÂ½š¼ ½Ã™½™Ã½Ã¼šÃš¼Ã ½šøøøøÿÿÿÿÿÿÿÿšÂšÃ¼š½Â½Ã½Ã¼š¼½Â½½Ã™ý½üÃüšÃ¼½ ¼š¼ ½š¼ ¼šÂ½ÂšÂš½Ãš¼½Ã½šÂšÃ¼š½Â½Ã½Ã¼š¼½Â½½Ã™ý½üÃüšÃ¼½ ¼š¼ ½š¼ ¼šÂ½ÂšÂš½Ãš¼½Ã½šÂšÃ¼š½Â½Ã½Ã¼š¼½Â½½Ã™Ã½Â½Ãøøøÿÿÿÿÿÿÿÿ½Ã¼šÃ¼ ½ ½ÃýÚß½½Ã™½Ã™½ ½šÃ½¼Ãš¼Ã™½™½Ÿ½™½  ½š½Ã½Ã¼ÃšÃ½Ÿ½Ã¼šÃ¼ ½ ½ÃýÚß½½Ã™½Ã™½ ½šÃ½¼Ãš¼Ã™½™½Ÿ½™½  ½š½Ã½Ã¼ÃšÃ½Ÿ½Ã¼šÃ¼ ½ ½ÃýÚß½½Ã™½Ã™½ øøÿÿÿÿÿÿÿ½Ÿ½½ ¼š¼Ã½ÂšÃ½¼½Â½½Ã½Ÿ½Ÿ½½Â½¼Ã½ ¼šÂ½š½Âš½Ÿ½™½Ã™½ÂšÃ¼šÃ™¼š™½Ÿ½½ ¼š¼Ã½ÂšÃ½¼½Â½½Ã½Ÿ½Ÿ½½Â½¼Ã½ ¼šÂ½š½Âš½Ÿ½™½Ã™½ÂšÃ¼šÃ™¼š™½Ÿ½½ ¼š¼Ã½ÂšÃ½¼½Â½½Ã½Ÿ½Ÿ½½Â½¼øÿÿÿÿÿÿÿ™½Ã™Ã½Ÿš¼ ½¼Ã ½Ã™Ã™½Ã½Ã½½Ÿ½½ ½Â½Ã½™Ã½Âš¼ ¼ÃšÃ¼š½ÃšÂš½Ÿ½½šÃ½™½Ã™Ã½Ÿš¼ ½¼Ã ½Ã™Ã™½Ã½Ã½½Ÿ½½ ½Â½Ã½™Ã½Âš¼ ¼ÃšÃ¼š½ÃšÂš½Ÿ½½šÃ½™½Ã™Ã½Ÿš¼ ½¼Ã ½Ã™Ã™½Ã½Ã½½Ÿ½½ øÿÿÿÿÿÿÿ½ ½½™½½š™¼ ½™¼Ã½½Ã½Â½Ã¼ ½Ã¼ ¼½ ýš¼šÃ½½šÃ™½ ¼ ¼š½™Ã½ŸÃ¼šÃ½ ½½™½½š™¼ ½™¼Ã½½Ã½Â½Ã¼ ½Ã¼ ¼½ ýš¼šÃ½½šÃ™½ ¼ ¼š½™Ã½ŸÃ¼šÃ½ ½½™½½š™¼ ½™¼Ã½½Ã½Â½Ã¼ ½Ã¼ ¼øÿÿÿÿÿÿÿüÙÙüڼýýÃüšÃ ½½Â½š¼ ¼½ ¼šÂ½Ã¼ ½Ÿ½ ¼š½šÂ ¼š½½ ½šÃ¼Ã™Ã™Ã¼Ãš¼Ã½Ã½ÃüšÃ ½½Â½š¼ ¼½ ¼šÂ½Ã¼ ½Ÿ½ ¼š½šÂ ¼š½½ ½šÃ¼Ã™Ã™Ã¼Ãš¼Ã½Ã½ÃüšÃ ½½Â½š¼ øÿÿÿÿÿÿÿš½šÃ½ÃšÃ¼Ãš¼Ã™½ÃšÂ½Ã¼š¼Ãš¼ ¼½š¼ ¼½Ã½½Ÿ½šÃ¼šÃ™½Ã™Ã™½š¼ ½Ÿ½½ŸÃš½šÃ½ÃšÃ¼Ãš¼Ã™½ÃšÂ½Ã¼š¼Ãš¼ ¼½š¼ ¼½Ã½½Ÿ½šÃ¼šÃ™½Ã™Ã™½š¼ ½Ÿ½½ŸÃš½šÃ½ÃšÃ¼Ãš¼Ã™½ÃšÂ½Ã¼š¼Ãš¼ ¼½šøÿÿÿÿÿÿÿ¼Ã¼Ã½Ã¼Ãš¼Ãýüš½Ã™Ãš½ ½Â½Âš½½ÂšÃ½Ã½Ã™½Ã™½Ã½ ¼Â½šÂš½Âš½¼šÂšÃ½¼Ã¼Ã½½Ã™½¼½š¼š½Ã™½Ã½Ã™Ãøÿÿÿÿÿÿÿš½ ¼ÃÃüšüšÂ™¼™¼™ ½Ã½Ãüü ¼š½™šÂš½¼ ½Ã™Ã½Ãš½ ¼¼Ã¼ š™¼ ¼š¼š™øÿÿÿÿÿÿÿ½¼ ½ÃšÂšÃ½Ÿ½Ãš½š™½½š½½ŸŸšÃ½Ÿ½Ãš¼ ™š½š¼ ™½Ÿ½Ãý½¼šÃ½™½š½š™½š¼ ¼ ½øÿÿÿÿÿÿÿ½ ½¼Ã½Ã½Ã¼ ½™ÃŸ½Ã½™™ ™½™Ãš½ŸÙü ½™½Ÿš½½šÃ¼Ã½½Ãš½Ÿš¼Ã½ ½Ã¼½Ã™½Ÿ½Ã½™¼š½š¼™øÿÿÿÿÿÿÿ½¼Ã½ÃšÃ¼šÃ½Â½Ãš½™ šš¼   ½Â½ššÃ½Â½¼š½™ š ½ ½Â½šÃ ½Â½š™½ ½¼™½¼ÃššÃ ¼š½™ š ½ ¼ššøÿÿÿÿÿÿÿŸ½Ã™½Â½šÂššÂššÂš¼š™½š™šÂš¼½š¼ššÂ½™™šÃ™Ã¼šÂš¼ ¼Ãš½Ÿ½Ã¼½ ¼ÃšÂš¼š™½™šÃ™øÿÿÿÿÿÿÿ½Ÿ½½Ã½™Ãš½Ÿ½šÃ™ ¼ ½™šš¼½½šÂ½Ãš½Ÿ½š ½ ½½š¼šÃ½½ ½š½½Ÿ½½ÃšÂ™½š™½š™š¼ ½Ã½™øÿÿÿÿÿÿÿ™½ ¼š™Ã™½ ¼šÂ½¼šš¼šÃšÂšÃ½šŸ½ ¼šÂÃ™š™¼šÂ½Ã½ŸýÃÙ½ ¼š™šÂ½½šÃ™Ã™š™š™½š™™š¼øÿÿÿÿÿÿÿ½Ã¼šÃ¼š½Ÿ½Ã™½™š™¼šÃ½½ÃÙ½™Âš½ ½½Ã™½ÃšÃ¼ ½½½Ã¼š™Ã™™½™š½Ÿ½šÂš½š¼šøÿÿÿÿÿÿÿŸ½™½™ ¼š¼š™½šŸÃ½š½Â½™Ãš½½šŸ½š™™½Ÿ¼šÃ½Â½™Ã½Ÿ½Ÿ½™¼½ÃšÃ™½™šš¼š™™š™Ãøÿÿÿÿÿÿÿ½¼ ½Ã¼šÃ™½™Ã™½š½ ¼šš™Ã™½¼¼½ ½¼ ™½™ÃÙ½™½¼š™Ãš™½š¼š¼½ ½¼ ™Ã½¼ ™™½¼š¼š½ ¼š™Ãš½™šøÿÿÿÿÿÿÿÙ½Ÿ½ ¼š½Â𙽙 ¼š™½¼š™ÃšÃš¼šÂšÃ™ ¼ š¼™š¼ ¼š¼ ™½š½ ¼š½Âš™½™Ã™Ãš¼ ¼š™½½™šÃššÃ™ ¼ š¼šššÃ™½½Ã™Ã𼠼𙽽™š¼š¼øÿÿÿÿÿÿÿ™½Ãš½™½™Ãš½¼ ½½š¼šš½™½½™½™½ ½™½™š¼š½ÂšÃ½ ¼šš™½™š™½™½™Ãš½¼ ½¼š½¼š½š¼šš™ ½½™™½™š¼š½ÂšÃ™¼™½Ã¼š½¼š½š¼šš™ ½Ÿš½øÿÿÿÿÿÿÿÙ¼™Ãš¼ ¼šÂš½Ÿ ½™½ŸŸš™šÃšÃ™½™Ã™½Ÿ½ ™š¼š™½šŸ½™š™½ Ãš¼ ¼šÂš½Ÿ¼ ¼ ½™½Ÿ½™½šÃÙ½Ÿ½ ™š¼š½ ½Ã™¼™Ÿ¼ ¼ ½™½Ÿ½™½š½Ÿøÿÿÿÿÿÿÿ™½š½šÂš½™ÃšÃ¼š¼šÂš½™½™½™½™½Ÿš½Â𙽙½š¼ ½Ÿ½š™š½™š½šÂš½™ÃšÃ¼š¼ ½½š¼šÂš½ššš½™½Âš™½™½š¼ ½Ÿ™š½½™½š½šÂÃ¼š¼ ½½š¼šÂš½šššÂš™øÿÿÿÿÿÿÿšÂ™™™½™Ãš¼š¼ ½šÂšŸ½™½š¼ ¼Ã¼š½Ã¼ ¼Ãš¼š½™™š½™šÃ™¼š™½™½Âš¼ ¼ ÃšÂ™™™½™Ãš¼š¼ ½šÂšŸ½™½š¼ ¼Ã¼š½Ã¼ ¼Ãš¼š½™™š½™šÃ™¼š™½™½Âš¼ ¼ ÃšÂ™™™½™Ãš¼š¼ ½šÂšŸ½™½š¼ ¼Ã¼š½Ãøÿÿÿÿÿÿÿ™½š½š¼ ¼š¼ ™½Ã™½™½Ÿ½šÂš¼šš½ ¼š½š™Ã™Ã™½š¼šŸ½™½šÃ¼šÃš½Ÿ½™½ ½½™½š½š¼ ¼š¼ ™½Ã™½™½Ÿ½šÂš¼šš½ ¼š½š™Ã™Ã™½š¼šŸ½™½šÃ¼šÃš½Ÿ½™½ ½½™½š½š¼ ¼š¼ ™½Ã™½™½Ÿ½šÂš¼šš½ ¼ÿÿÿÿÿÿÿÿÃ™Ã™Ã½š½Ÿ½Ã½ ¼Ãš¼½šÂ½šÃšÂš™Ã™½Ÿ½Ã¼š½™½Ÿ½š¼š½Ÿ½ÂšüٽÙ½™šÃ™Ã™Ã½š½Ÿ½Ã½ ¼Ãš¼½šÂ½šÃšÂš™Ã™½Ÿ½Ã¼š½™½Ÿ½š¼š½Ÿ½ÂšüٽÙ½™šÃ™Ã™Ã½š½Ÿ½Ã½ ¼Ãš¼½šÂ½šÃšÂš™Ã™½ÿÿÿÿÿÿÿÿÿ¼š½šÃšÂ½š½™Ãš¼ ½™Ã½ ¼š¼š™½™½™š¼™š½Ÿ½™š½Ÿš¼ ½¼š½Ÿ½šÃ½ ½™Ã™½¼š¼š½šÃšÂ½š½™Ãš¼ ½™Ã½ ¼š¼š™½™½™š¼™š½Ÿ½™š½Ÿš¼ ½¼š½Ÿ½šÃ½ ½™Ã™½¼š¼š½šÃšÂ½š½™Ãš¼ ½™Ã½ ¼š¼š™½™½™ÿÿÿÿÿÿÿÿÿÙý™¼šŸ¼Ãýý½™Ãš¼½ ½™½™½™š¼™š¼š™¼šÂš¼š¼š¼š ¼š½™Âš¼½Ÿ½š¼ ÃšÃ™Ã½™¼šŸ¼Ãýý½™Ãš¼½ ½™½™½™š¼™š¼š™¼šÂš¼š¼š¼š ¼š½™Âš¼½Ÿ½š¼ ÃšÃ™Ã½™¼šŸ¼Ãýý½™Ãš¼½ ½™½™½™šÿÿÿÿÿÿÿÿÿÿÿš½½ ½½šš™Ã™Ã™½™Ã™¼š¼š¼š½™½™™¼š½™½½š¼šÂš¼¼š¼Ã½š¼ ½Ã½¼ ½™½™½š½½ ½½šš™Ã™Ã™½™Ã™¼š¼š¼š½™½™™¼š½™½½š¼šÂš¼¼š¼Ã½š¼ ½Ã½¼ ½™½™½š½½ ½½šš™Ã™Ã™½™Ã™¼š¼š¼šÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿú-ü-&TNPP &ÿÿÿÿڼÚ½Ÿ½š¼½Ÿ½Ã™½Â½šÂššÂš¼½ ¼ÃšÂš¼š™½™šÃ™½š™š¼Ã™½™½Ÿ½½Ã½™Ãš½Ÿ½šÃšÂ™½š™½š™š¼ ½Ã½™ ¼ ½™šš¼ ½š¼šÃ½½ ½š™ÃšÃ¼šÂ½Ã½½Ÿ½½Ã½™Ãš½Ÿ½šÃšÂ™½š™½š™š¼ ½Ã½™ ¼ ½™šš¼ ½š¼šÃ½½ ½š™ÃšÃ¼šÂ½Ã½½Ÿ½½Ã½™Ãš½Ÿ½šÃšÂ™½š™½š™š¼ ½Ã½™ ¼ ½™šš¼ ™½ ¼š™Ã™½ ¼šÂ½½šÃ™Ã™š™š™½š™™š¼šš¼šÃ™½¼šÂ½Ã½ŸýüýšÂšÃ½šŸ½Ã™½ ¼š™Ã™½ ¼šÂ½½šÃ™Ã™š™š™½š™™š¼šš¼šÃ™½¼šÂ½Ã½ŸýüýšÂšÃ½šŸ½Ã™½ ¼š™Ã™½ ¼šÂ½½šÃ™Ã™š™š™½š™™š¼šš¼šÃ™½¼š½Ã¼šÃ¼š½Ÿ½Ã™½™Ã™™½™š½Ÿ½šÂš½š¼š™¼ ½¼šÂš¼½Ã™½ÃšÃ¼ ½Ÿ½Ã½™Ã™½Ã½½Ã¼šÃ¼š½Ÿ½Ã™½™Ã™™½™š½Ÿ½šÂš½š¼š™¼ ½¼šÂš¼½Ã™½ÃšÃ¼ ½Ÿ½Ã½™Ã™½Ã½½Ã¼šÃ¼š½Ÿ½Ã™½™Ã™™½™š½Ÿ½šÂš½š¼š™¼ ½¼šÂš¼Ÿ½™½™ ¼š¼š™½šŸ½ÃšÃ™½™šš¼š™™š™Ã½š½Ÿš½™½ ¼šÃ½Â½™Ã½Âš½Ÿ½Ÿ½šÂš½½Ÿ½™½™ ¼š¼š™½šŸ½ÃšÃ™½™šš¼š™™š™Ã½š½Ÿš½™½ ¼šÃ½Â½™Ã½Âš½Ÿ½Ÿ½šÂš½½Ÿ½™½™ ¼š¼š™½šŸ½ÃšÃ™½™šš¼š™™š™Ã½š½Ÿš½™½ ½¼ ½Ã¼šÃ™½™Ã™½™½¼š¼š½ ¼š™Ãš½™š™Ã™½¼šÂš¼š¼š¼½ ½¼ ½ ¼š½™š™½™Ãý¼ ½Ã¼šÃ™½™Ã™½™½¼š¼š½ ¼š™Ãš½™š™Ã™½¼šÂš¼š¼š¼½ ½¼ ½ ¼š½™š™½™Ãý¼ ½Ã¼šÃ™½™Ã™½™½¼š¼š½ ¼š™Ãš½™š™Ã™½¼šÂš¼Ã™½Ÿ½ ¼š½Âš™½™Ã™Ãš¼ ¼š™½½™š¼š¼š™ÃšÃš¼šÂšÃ™ ¼ š¼™š¼ ¼š¼ ™½ššÃ™½Ÿ½ ¼š½Âš™½™Ã™Ãš¼ ¼š™½½™š¼š¼š™ÃšÃš¼šÂšÃ™ ¼ š¼™š¼ ¼š¼ ™½ššÃ™½Ÿ½ ¼š½Âš™½™Ã™Ãš¼ ¼š™½½™š¼š¼š™ÃšÃš¼šÂ™½Ãš½™½™Ãš½¼ ½¼š½¼š½š¼šš™ ½Ÿš½™½½™½™½ ½™½™š¼š½ÂšÃ½ ¼šš™½™š™¼™½Ãš½™½™Ãš½¼ ½¼š½¼š½š¼šš™ ½Ÿš½™½½™½™½ ½™½™š¼š½ÂšÃ½ ¼šš™½™š™¼™½Ãš½™½™Ãš½¼ ½¼š½¼š½š¼šš™ ½Ÿš½™½½™½™½ ½Ã™¼™Ãš¼ ¼šÂš½Ÿ¼ ¼ ½™½Ÿ½™½š½Ÿš™šÃšÃ™½™Ã™½Ÿ½ ™š¼š™½šŸ½™š™½ ½Ã™¼™Ãš¼ ¼šÂš½Ÿ¼ ¼ ½™½Ÿ½™½š½Ÿš™šÃšÃ™½™Ã™½Ÿ½ ™š¼š™½šŸ½™š™½ ½Ã™¼™Ãš¼ ¼šÂš½Ÿ¼ ¼ ½™½Ÿ½™½š½Ÿš™šÃšÃ™½™ÿ½š½šÂš½™ÃšÃ¼š¼ ½½š¼šÂš½šššÂ𙽙½™½™½Ÿš½Â𙽙½š¼ ½Ÿ½š™š½™š½½™½š½šÂš½™ÃšÃ¼š¼ ½½š¼šÂš½šššÂ𙽙½™½™½Ÿš½Â𙽙½š¼ ½Ÿ½š™š½™š½½™½š½šÂš½™ÃšÃ¼š¼ ½½š¼šÂš½šššÂ𙽙½™½™½Ÿÿ™™™½™Ãš¼š¼ ½šÂšŸ½™½š¼ ¼Ã¼š½Ã¼ ¼Ãš¼š½™™š½™šÃ™¼š™½™½Âš¼ ¼ ÃšÂ™™™½™Ãš¼š¼ ½šÂšŸ½™½š¼ ¼Ã¼š½Ã¼ ¼Ãš¼š½™™š½™šÃ™¼š™½™½Âš¼ ¼ ÃšÂ™™™½™Ãš¼š¼ ½šÂšŸ½™½š¼ ¼Ã¼š½Ã¼ ¼Ãš¼š½ÿ½š½š¼ ¼š¼ ™½Ã™½™½Ÿ½šÂš¼šš½ ¼š½š™Ã™Ã™½š¼šŸ½™½šÃ¼šÃš½Ÿ½™½ ½½™½š½š¼ ¼š¼ ™½Ã™½™½Ÿ½šÂš¼šš½ ¼š½š™Ã™Ã™½š¼šŸ½™½šÃ¼šÃš½Ÿ½™½ ½½™½š½š¼ ¼š¼ ™½Ã™½™½Ÿ½šÂš¼šš½ ¼š½š™Ã™Ã™ÿÿÃ™Ã½š½Ÿ½Ã½ ¼Ãš¼½šÂ½šÃšÂš™Ã™½Ÿ½Ã¼š½™½Ÿ½š¼š½Ÿ½ÂšüٽÙ½™šÃ™Ã™Ã½š½Ÿ½Ã½ ¼Ãš¼½šÂ½šÃšÂš™Ã™½Ÿ½Ã¼š½™½Ÿ½š¼š½Ÿ½ÂšüٽÙ½™šÃ™Ã™Ã½š½Ÿ½Ã½ ¼Ãš¼½šÂ½šÃšÂš™Ã™½Ÿ½Ã¼š½™ÿÿÿÿ½šÃšÂ½š½™Ãš¼ ½™Ã½ ¼š¼š™½™½™š¼™š½Ÿ½™š½Ÿš¼ ½¼š½Ÿ½šÃ½ ½™Ã™½¼š¼š½šÃšÂ½š½™Ãš¼ ½™Ã½ ¼š¼š™½™½™š¼™š½Ÿ½™š½Ÿš¼ ½¼š½Ÿ½šÃ½ ½™Ã™½¼š¼š½šÃšÂ½š½™Ãš¼ ½™Ã½ ¼š¼š™½™½™š¼™š½Ÿÿÿÿÿÿÿ½™¼šŸ¼Ãýý½™Ãš¼½ ½™½™½™š¼™š¼š™¼šÂš¼š¼š¼š ¼š½™Âš¼½Ÿ½š¼ ÃšÃ™Ã½™¼šŸ¼Ãýý½™Ãš¼½ ½™½™½™š¼™š¼š™¼šÂš¼š¼š¼š ¼š½™Âš¼½Ÿ½š¼ ÃšÃ™Ã½™¼šŸ¼Ãýý½™Ãš¼½ ½™½™½™š¼™š¼š™ÿÿÿÿÿÿÿÿ½½šš™Ã™Ã™½™Ã™¼š¼š¼š½™½™™¼š½™½½š¼šÂš¼¼š¼Ã½š¼ ½Ã½¼ ½™½™½š½½ ½½šš™Ã™Ã™½™Ã™¼š¼š¼š½™½™™¼š½™½½š¼šÂš¼¼š¼Ã½š¼ ½Ã½¼ ½™½™½š½½ ½½šš™Ã™Ã™½™Ã™¼š¼š¼š½™½™ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿú-ü-&TNPP &ÿÿÿÿDocumentSummaryInformation8ÿÿÿÿÿÿÿÿÿÿÿÿiœ Current User()*+þÿÿÿ-./0ÿÿÿÿÿÿÿÿÿÿÿÿ56789,2@ABCDEFGHIJKLMNOPÿÿÿÿÿÿÿÿÿÿÿÿUVWXYZ[\]^þÿÿÿ`abcdefghþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿDesign Template Slide Titles˜ 6> _PID_GUIDäAN{93742905-809D-11D2-9B95-00A0244D177F}ö*_À‘ãôSimon Peyton Jonesèé(Z Óà€ ò</È 0ÒÕ˜·DTimes New RomanÈ·È·Ô³…Þ0ø³ø³ ß0·DArial BlackmanÈ·È·Ô³…Þ0ø³ø³ ß0"©  @£nÿý?" dd@ÿÿïÿÿÿÿÿÿ  @@``€€ ¨ð ð ð,Rð$˜îNû§²ÝaR­A€ ÇGÿ (c ð$ƒ¿Àÿ@ñ÷ðó€Ð‹ÿ úgþý4dddd´ ß0ü³þÊöÿÿ€øÿÿpûêpû-?Ù Ú%ðóêø™ ï `ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²²`ð ÿÿÿÿÿÿÿ™ÿÿÿ–––`ð ÿÿÌff3€€3™3€3ÌÿÌf`ð ÿÿÿ333ÝÝÝ€€€MMMêêê`ð ÿÿÿ€€€ÿÌfÿÌÌÀÀÀ`ð ÿÿÿ€€€ÀÀÀfÿÿ™`ð ÿÿÿ€€€3™ÿ™ÿÌÌ̲²²£>ÿý?" ddÏÿÿïÿÿÿÿÿÿ£|ÿý?" ddMÏÿÿïÿÿÿÿÿÿ € ¨h €" Ï € k7€»ÒŸ £nÿý?" dd@ÿÿïÿÿÿÿÿÿ   @@``€€P£R  h Ï 7 Ÿ`£ p£>  €£>  Ãð»ððSð( ðõõõõõõõõõõõõõõõõ ððð ð ã ðT€4|–€‚K@ƒ–€„K@‡¿ƒ¿Àÿ ðWÇ“ úðà  ðTŸ¨ Click to edit Master title style¢!ª !ð4 ð Ó ðN€Ô{–€‚K@ƒ–€„K@¿ƒ¿Àÿ ðÇ“ fðà  ðžŸ¨RClick to edit Master text styles Second level Third level Fourth level Fifth level¢!    ª Sðñ ð Ó ðN€t{–€‚K@ƒ–€„K@¿ƒ¿Àÿ ð|Çï½ðà  ð[Ÿ¨*¡ø¦ñÏhhÏÏ77ŸŸðó ð Ó ðN€{–€‚K@ƒ–€„K@¿ƒ¿Àÿ ð|‰Ñ½ðà   ð]Ÿ¨*¡ú¦ñÏhhÏÏ77ŸŸðó ð Ó ðN€´z–€‚K@ƒ–€„K@¿ƒ¿Àÿ ð|k“ ½ðà  ð]Ÿ¨*¡Ø¦ñÏhhÏÏ77ŸŸðH ð ƒ ð0ƒ“éI@”ÁÏ¿ÿ ?ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²² º,Blank Presentation.potî6ï€ æðÞ ððvð( ð   ðð>" ð C ðŽ€x–€‚K@ƒ–€„K@…‡¿€ÿÿ̆A‡Á¿Àÿ¨)¨)?¿StationeryðZ Ó ð€Ÿ¨ Haskell 98¡"  ,ª¦ñÏhhÏÏ77ŸŸðH ð ƒ ð0ƒ“éI@”ÁÏ¿ÿ ?ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²²r0#Ä õpèé(Z ³à€ ò</È 0ÒÕ˜·DTimes New Roman¬·¬·¸³…Þ0ܳܳ ß0·DArial Blackman¬·¬·¸³…Þ0ܳܳ ß0"©  @£nÿý?" dd@ÿÿïÿÿÿÿÿÿ  @@``€€ ¨ð ð ð,Rð$˜îNû§²ÝaR­A€ ÇGÿ (c ð$ƒ¿Àÿ@ñ÷ðó€Ð‹ÿ úgþý4ddddè³ ß0à³þ²öÿÿØ÷ÿÿpû[pû@?Ù Ú%ðóêø™ ï `ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²²`ð ÿÿÿÿÿÿÿ™ÿÿÿ–––`ð ÿÿÌff3€€3™3€3ÌÿÌf`ð ÿÿÿ333ÝÝÝ€€€MMMêêê`ð ÿÿÿ€€€ÿÌfÿÌÌÀÀÀ`ð ÿÿÿ€€€ÀÀÀfÿÿ™`ð ÿÿÿ€€€3™ÿ™ÿÌÌ̲²²£>ÿý?" ddÏÿÿïÿÿÿÿÿÿ£|ÿý?" ddMÏÿÿïÿÿÿÿÿÿ € ¨h €" Ï € k7€»ÒŸ £nÿý?" dd@ÿÿïÿÿÿÿÿÿ   @@``€€P£R  h Ï 7 Ÿ`£ p£>  €£>  Ãð»ððSð( ðõõõõõõõõõõõõõõõõ ððð ð ã ðT€4|–€‚K@ƒ–€„K@‡¿ƒ¿Àÿ ð>Ç“ ±ðà  ðTŸ¨ Click to edit Master title style¢!ª !ð4 ð Ó ðN€Ô{–€‚K@ƒ–€„K@¿ƒ¿Àÿ ðÈÇ“ fðà  ðžŸ¨RClick to edit Master text styles Second level Third level Fourth level Fifth level¢!    ª Sðñ ð Ó ðN€t{–€‚K@ƒ–€„K@¿ƒ¿Àÿ ðuÇï¤ðà  ð[Ÿ¨*¡ø¦ñÏhhÏÏ77ŸŸðó ð Ó ðN€{–€‚K@ƒ–€„K@¿ƒ¿Àÿ ðu‰Ñ¤ðà   ð]Ÿ¨*¡ú¦ñÏhhÏÏ77ŸŸðó ð Ó ðN€´z–€‚K@ƒ–€„K@¿ƒ¿Àÿ ðuk“ ¤ðà  ð]Ÿ¨*¡Ø¦ñÏhhÏÏ77ŸŸðH ð ƒ ð0ƒ“éI@”ÑÕ¿ÿ ?ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²² º,Blank Presentation.potî6ï€ æðÞ ððvð( ð   ðð>" ð C ðŽ€x–€‚K@ƒ–€„K@…‡¿€ÿÿ̆A‡Á¿Àÿ¨)¨)?¿Stationeryð`0ð M ð€Ÿ¨ Haskell 98¡"  ,ª¦ñÏhhÏÏ77ŸŸðH ð ƒ ð0ƒ“éI@”ÑÕ¿ÿ ?ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²²r0>aõp@haskell98-report-20080907/report/h98.gif0000644000175000017500000003706611345221573017067 0ustar marcotmarcotGIF89a¸r÷E<.C<0F>2D>4FA5FB8HA4GB8ID9IF>KH?\R@\SF^TD_VH^WHaWGcZFaZKc^Pk`NfaUmbQofWsfPrfUqhVukTqjZtk[vmZtl^ykS}nVymXvp_{p^xq`sa€r\…y_u`‚xf†{fƒ{k„}h…}kˆ{gdˆ€l‚kŒo‡‚r‰ƒr‰†v‘i’…i˜‡mŸŒn…p‡u”‡q”Œv˜‰s˜tw˜x—~žqœyœ‘~£‘u¤p¤“v¢“{¢•|¦–~©“p©•t©šy¯›{­™|±z€€€Ÿ–¢—€¦™‚ šˆ£œˆ¦œˆª‚©Ÿ„¬›‚­Ÿƒ¯Ÿ…«Ÿ‰°ž«¢‰­¡‰³£€´ ±£¯£‰³¤‰²¨Œ½«‡¸¨½¨ˆ½«°¥´¨·­’¹¬’½­½±“¾²—¸°š¹´Ÿ¾´™Ã«…Á®É¯†Ä²ŒÏ·Å²•Æ´–Á³—¶žÆ¶˜Éµ•Ͷ“ȶšÎ»“ʼŸÍ¹›ÍºœÌ½œÐ·ŽÛ¹…й’Ö½”ѼšÕ½˜Ç¼ È¹ É¾¡Ê½¥Õ˜Ý—ÜÃÝɞ̿¡ÏĦÑÂ¤ÒÆ§ÔÀ ÕÄ¡ÖŤÒÅ«ÕÇ©Õȧ×Ì­ØÂ ÛÆ¦ÝÆ ØÇ©ÝȦÙÊ«ØÈ­ÚÍ®Þ̪ÜÍ®ÐȱÙ̱ßÓ³ÜÒ·àÂ’äÆ˜ãÉçÊëΖâʦäÏ£áÌ«âέéϧàϳåÓ¯ìÒ¦ïÖ êÕ©íÕ¯àаàÒ·ãÖ²áÕ´åÓ³æ×²çÖ¹ãÙ¾æÚ¹èÒ°é×±ìÖµèÖ¸éÚ¹éܺëÜ¿îÝ»ïܾòÜ­óàºñã½ôä½îßÂëàÄìåËõãÄöæÀôçÄöçÉ÷éÅóèËôëÏùîÐúó×ÿÿÿ!ùã,¸r@ÿÇ H° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ£Ç CŠI²¤É“(SšÀ²¥Ë—0cÊœI³¦Í›8sêÜɳ§ÏŸ@ƒ J´¨N’tESM—SjPQ“ j´«X—iÕê­«W¯Ô¦a½Š ×ÕkׯF 0fÊâÚškKY]¹qãæ*»ìT©S§Š X+®e‡+½ª+oc§L+›–Ø™Vg˜-/smæ«Þ¦MË5–Zg±¤Éš½JÍéÒ¦O§J¥ZUíÖ­_¿B;vu´´cñ•ýV.]¼vï*˵·¯ßÀƒ‹.†Ø°âÅ•In {2_Í›1_ÿ>Í9Z×Ñ¥¯¢ÆZkk¥‘c»ZÕªíÛ¹uóf8VámgÜ]Ê)·Üa€õÉ6U/½4æÖ„Úqw[b¢‰ÖÙX¼6Ë,ˆqà eæy³aUjG0Ú´X„FÃM4áUÃV€m… g®açd‹Å¥KYe¨‡î5…obeÈ™ˆ&båLƒ¡„“":jedŒêq‰ˆ!RfV”b¡ø˜.³±¨M}½œ&ãU›Ùx#`§ö™R=þ¸æRâ"™†G†Él†6)Ú“ÜDyÕ” Îg%dYj ™˜Õ-óå~êH&.#’ˆf4j Ù¦‹/†9#Páê«ÿ—ìù¶äm·):ãVœær‚MaÄ%‹,lZIœ.zØ´‚S”™I™kÚ©GM”ÎxV-®Øfèè4Ë|ø .‚ëåUµÔ"š/¾€;M)¥ˆöá,ºd8Z5Á!¶ãжë¸Xå¢L3Í\£ŒÀÊ´˜—–Ãke/²9¥°T OØKM%Àí4ÔÔ¤¾šNÓ•zZÍòm¸¢QGÚ FM2p\Ç…ð°lBxìÃÔ0,›ÎM9Ûê«°B@‹ÚÌá~âÊém"޸̪§TR‚Mo¸Õ ÄWû©Ë ÊboUºP³ÊA°GÓFr{Y ?™½Õ,êF£Íõž¦67¡ÕŒ€Uÿ’ Zš°Ü“Èg3TºÔ„B}|fLÓ [åÙ±ˆioU-fbÕ”ˆ|iºÕ5ibèUÐô¦"vRSZ2k© ‹ Cì–Ö†þ£×ñþ 4 Mt4e‰%~±‹kµÓ4ÝôV2&ßh8/Eñ‚ªÉ&5’¢ .qývÕßÑð@“ 26êÍ+5A †¢Ì¸ê4Ö(Ÿ­Çs×´M(ïôU#rCLM[›.b ]Ô‚ I ”Q‰E,¢‰£É ®‡=îÔdD#ZUÂÁ¿®4MF˜©ò( =–”@xtòK@4”¥*¸`Ü x@Ú9NéA§jH‚ÒÐÿzw£­%h¡»pœ†ÈëŒWb4#øÅ+°‰4$fe(,ž°‰Ø¥¨ixÀ& @‚#2ÐDÓòƴĤ6­t A(ÝNŒ`REã 9Y@MðŒ ‰¨3ÖˆM¼Ð/xA d8Ã" I2X —Dƒ&Ãà7Yé‚òòc4j’÷@@rœÖ¹TÇ\qªP4Kg‚2á\*u¨I“¦(Ír&‡DÌaâ¦x}1,õÉ’6ŒEY´K=B ÚC€•E0{“p´1%*¯Õ8¸1Ný5í—39C^”½å0'5š°É §Äh£„-ÁŠWôHÿO4è5yƒÃÁM¨ðÂ&/0'7Pa”ÓeÅs5aA%&Z <â‚e—zž¥O¯x,Ž„âF†â¹iãšs6YM …h‹¹Ê:±÷ÎÔÀ’FÜ ¸€ˆ‹hºªw¢QâXÂvÊú'i™©“EèŒqŠ× h‹Â!ŽmíEkѰ °½ôH™qF.0³£wþæ¥W%Z7Öª ­Z³{¢$ÕÇêØ¼4õÑ3”ËÔ2dd kp«sÚòhŒÎƒ1zmƒF RÅã p6¶©N…jT‰FU©íªn½lf±Z¨°ŽuGbM Z/«Ön´È­2M©æHWÊ­Ö4x‘0µR>¿ÿζc,o+ÔÃuƒŠMx,ÓØ¥B–œâœìT«ºU¯n¶­Í=©Z<댲„ö,>å]ïÊR‰Õ@¥,ì¼Õ2À©p‚óƒgåæVÑ‚Uöbu­¦½FÀ°šÁ B8^M‹rÏŠUáø÷ªK¡¯ÀþFß·¦§®Wñ«x.ó$#…*ÞHÌœ ÅËŒânÜõ.5¸^·å5/zé+U÷æ—¾lEKÀêkßûš´hg%(¹éߪ½z)ðIáºÚºŠÅ¯ž¹Mƒ5D9óeÂGªpF1Œ‹î²fÃqécgBâóò7S]¯€ÑÊ֬긾UIËVÏ"ãô '»Ú­KJ#eá¢ÿ¯ñËÍðús f´¨níªs½ÚV´ÊwÅ,6X¤‹ªû¢å7Ãc Z˜20‚Áu/ÁK¾8ó•Üj+«"•Q50I÷Púô“ÛŒ8›Ï+sæ¯×ªU€¹UŤ´—¿œA¦¤÷Åõ94Z8Ø=#¾,/ýŠ´p']¢ótåÒüsϦ]Ôé7‰ú®rSKm²ò澞š‰†Uõ[­gX¿TÖò-‹me¹±dwèþéGÒÍîv»ûÝðŽ·¼çMïzÛûÞøÎ·¾÷Íï~ûû߯·JNð‚üàO¸ÂÎð†;üá¸Ä'NñŠ[üâÏøÅ .z2¦-ÿäU¦ÿ¼Ó\Õ½ïÿl´¢»·ÎfüËå. Àdnç™[Ø9€Y„å3LÆ J;Qžöxc<]hsæùn*œ±j?}WÇùDÔùÔ‡•É»UF›tbö¦Üˆ¾–9Ì_.v˜3£æÊ¸9ÎÈàÃ$†O>;…>±¬&G:Bºaù"¨öÀ2Ng’j¥ž!ªƒüê"×zÉEsr¯3ç׿±u^fóÊS¾hO{O9 UåMT¢ÊCi›[UBEŽ]é-˜È;¨¤´¾À°ü\*±Î½L':VqX#­5ج 2H»é‘W –»6I-ÂíÜRêÃN¨€>RöÁ”Q_꫞7<ö-öXì˜Ì´Ï ÿ¤¡3ƒx¸[ï}wüT÷Ârør‹û_™| 7ßõŸ§}¤|›é›^•©—mØÇzçz{/× à~î„ äW º£f®Wq1Q)gk1%ijA9Šrè$M@[¾—PF DOÓ@Q¥ LLRG%·x:5 ra[‡aÂõ.¥@m:ua»ñ.Vxº0ƒ„²hPWà/¸$t5¡r|Ÿ‘§q¸ó#÷r%òI4¡Ȧ6¤¤.pÃd27Ãö!9H'ÁS³°=±Ø0’Ç@5Wƒ@6<qZQH'êA…ŒÁ~õ1 Yø#W£CL‚)˜]½Ã^¯ÿq$Šš"'vã‚"x¿Ra%WƒC=ô:&H( $D¢ƒ8j²$ šÁ?¸’d²W;Hƒ&‹½$'68 fRQò7Ñà5Aä‘+`"/†!aXáN§ 1'3-R)Y£ ô:2!NAJˆCTÚqAN£#‡‹vÆl¸ @ ƒ:ŋӰ5 O3q5l¸Ð4qÍHËĉ8$’Q9S,ÿh…<ňB“´â‹§±7¿ð {…+òƒ/à Hø(À†¤â€+`6°`æ6ËÀO0‘wÀ@B¦smÔ@/4a/¢ø#"ÿÓ 7¡* ` Ôð&>A3ÁmÒ­qAjá_ á y¥)æD73‘uT A¶ òø8ÀÃ)¢Ñ  .ÔÛø#œ1´aÔ0,C‰8ÕÓÆ9M³"SŠv¬˜¬¸7N"&7ò!Oà }å*`dàEôd@Æd@\£8è„2ø#l‚,#Gí8+`Yi2³7ݲ7‚yÉr@ÚP"À~°Q/à5lv¦§6K„†P™4Ñ@ 5±Þsh#9œ±¹ ÷C¨€œòbL¢a@µ/N1¥ç C)ºà ò2—ÑyvÉ”ÿÅADƒzçÁ?ÊÃ-˜Eúc‘3á Ñ»!Wј4‘%ç º04á•@u à">S”p<°&L #˜iWÁ621REH € åyP5!Î "*"UP”À<©§ «p€'p’4žP8Ô8Ê 8f±NÝÈ•ùWƒØQúr#3P{ÐQÞ° ÁÙ=Suf5Qé¹`{ðÃV"òä6”Bw¸[ÞÙÔT($fYBõ£ßð à$hj#âT f:¹055ÑX0ïT`Ѱ•3±"eÓ ®@5a’&¨9ð¨„Á V€’5ÿ1[À Ù&W§P4QÄAú’ 6¡ÃআUÂ` t ÇP›]¦P)›x& ®Ú ÒКÓЍHb-œ‚l_p7ñ‰°J`JcbŠ©j@9g` ÌÁ^EsŒ¶Ctº¬¿ód_!PyHv5JéÖ;ú'GÒF U2‚Á.Ôñ4’y/•ëEZYugIjURõwŽhb,ÆV®ærâ6mqÕ®•(½dït‚[WqT¹•rÒMõá­l®SV ìR åJNÀ!0ô•M|FZ°Öe5¦^ÖT(HT±ÌZ_ðÕV®Öl…ÖGѧ/Á§*;‰Îƒuû\^QEÂÒÓ­m¶ZË-ã*±{UgÑhØôz»UZűÿeUòªkÌڥߙz¿eÆäa©<¨F4hj¯§Õx&«e0†—ýqM‡6×€„¤R`ÙöµsUó=~<°Í"S´/-¨D {JIæ ¦QkS;e¦iµL„µâ`ZÐÕU&–Y'÷µÞ¶/E+¿ñx«¦WáUÑ@`E“R™›Qª·MiuK'Hƒ·Õ'G‘ú”}[|¦+µO‡œúsµ-’µ¦Åm\˸Ìê´¢_í¥há/¤‚fiÿ–W¼Æ{¼È›¼Ê»¼Ìۼλ¼½Ò;½Ô[½Ö{½Ø›½Ú»½ÜÛ½Þû½à¾â;¾ä[¾æ{¾è›¾ê«¾,T¦)D5lß°–v0ãNPˆŸúN²N™›r€0‡£ Ø9Âda¬@´ X¢%â'y)’S]¢(Û Gq±¢E+–Áf¦á%_4jQ¿Üò‡¡!õË=SSúK`55€¶vKájHHÀÖ9œÃf‘˜Ã„%­S!®ÁŠœ'ÌŠLrÁ®§Áa+%{eJŒ[#ÂSAÂZ1¿(œQö[0ø;V¡õ»üžßÀ XÃyÁ ‘]¤ú7Jÿ"¸ØRl£· ö=a»Á&uvÝ׌ÊqvyÑ9u{ÒÑÖñCm¼ØAÀ:%9›‘w S]€8:ÀZ-íQ-OÆFˆ²ÆÀÐÆ­Ô¹A*s}̶¤áˆÚpvÌ{3—qaÊq‘Q8‡'ƒ!9y¢tˆ(|BÀÞwàqiêY]M ÉŽ"ÉfAÉ=Ö3—¬™¼›l¢_±Z†Êv<ʇVÊx|²ª¬ ¬¬yrQbÄÉ&)+eòË¡µR6”Ò¥ÌGRT«õg7ss‘Â@®‚áXåÚɾçàL¼!N`’JÍìG0¤2˜3µàÜn1ιÉ< ñQú:”´ÿ9„î ¤âñ,ÏÆ£ÝÅøœÏÎ oœŒˆĤÐôw½©GQò¾ß¥ÐÕÂзãÐnòO†r‰ç|u¬ñi¦øJžÌ Ï'K õWÈJÂÖ~âÖ2‰í¼°1M×Ô¶SQ-t+BÕ|Mµˆñ%&‚ÍÖvã~^í@w0­ÃlU\ËM‘Äá'»}S'mµÿ1 —@ ¢ ‰pÜÇM ÊŠÜ-UqᎠž ÝŽà ØÝœ€iMÌ厮1 rÖ·3$AÌwQd&ܶҿ|«ca ƒpŽpƒpßx`߃ ½ K¿Jµ<®„/³ðÜ8t0.bu%x‡  šP܉ðà¢ð žñP¸à~0š ÜöÍàƒÀ à D1åv˜ÃÞðgâX!M°*P™°<@†À)”¢Û2QB¢ÁðW°Ëɰ+p›À Vñ£ßÂË\àm‘;-ṫžµ½­Bs_ŸÆf• O—|—á•:EÌœÑ6Ñ "3:!Œ Oÿ5•0 Àƒl]i9u$àèÊ(ì%žã%så,B·Aø!µ ï/?b.£ šNZÞ‚^n]bñó:W^æV“3YHWcF)+çà¢1 Xoî9Ö[ãx  ÀY©•å¢qCúEéÉh鯒…hi%óq%'a¦æ`g¥ŒèÊIìˆKUX^•¦‘lew*¨žŽÃ?¸¨…¢0TŒ:ËâØò¤… æ0k£ËnÖŠùdÊibªÙ—Ã%n“­Û\Çî+ãa19+œd;ÈÇ®ªÁ­¨^_"V‚õŸÃ¸¢Œƒ½yßÝe3 BY|m§!¿˜kµÔ: ¶ê÷šçF,QË,P¡›yÄv¥´ýÔ„¢/Þöî !þéÌs¬éV7DbŽ7fÙËþ²¡äV®|%ß&¿sß±´ÜD^ÚÀëTøZ»! Ÿ”×¶­n;\¦cžÜ䀮˚›âJ>´5)mBÒéO‡zÔ¥>uªWÝêWÇzÖm(®/ÿéƒêzØÅ>v²—ÝìgG{ÚÕ¾v¶·Ýío‡{Üå>wº×=Ú_gºÝõ¾w¾÷Ýï|à?øÇáÝð‡G|â¿xÆ7Þñ‡|ä%?yÊWÞò—Ç|æ5¿yÎwÞóŸ}èE?zÒ—Þô§G}êU¿zÖ·Þõ¯‡}ìe?{Ú×Þö·Ç}îu¿{Þ÷Þ÷¿~ð…?|âßøÇG~ò•¿|æä¯4Ô…Rnú ”s„‚ÊÀEX“C58‡ Q¶¡rècBRÙrLF¾BAö÷™šê¿ M”!ÿù ¨mLjDÉB¯mœ5&Â<4“594—ŒŽ)ÀÉ>>ñ |«¾æÊììíë*ÿ®Š¤Ê…)+ñËË‘%:?930Ôj? ¢&ñY†ž˜¿àXA«0¹?üsýS«þ ",¬­à/(3@yA@Øbécêë¦ëË>$¡@ʲ@ÊÁ@ ´ìÀ¿x$Œ‰ƒ°<X?ÐÄq Œ¸÷S6¿ÊY©yëÀðÓ´M;Ÿ/ƒ#b¿eh#õ£ÃW‹¨Õ "dAÝȈSP¡/tŸ{Áf‹¢<{Ÿ Q?Ày‰:‘š.\ úZC2Œ$)ì¥ñ ¿ó#+Yº!YJ¿<çÒˆê/ûø©dA;5?\ lš—rm(DL DÌ#’ÛB;zĉDRÔ´ÿë2šâDãÀIJÒD«§7‚#ˆ¼'û7[ »X }Ûmú7RŠÉ!„B²Š©G Aóq&fˆ‰P¤ 6:…R@Çû‹|AQ6à˜ ˜¨…˜…S6*³þEW| »¨¬²xXtŸåŠÆ¨AÁ;3•ˆ&Eù­m4µn<38 ǘH(r4ÇsLÇuÄ¿¤â¯dQÁ½šÇûh®{$?äÇ2² Ô²©C;Ь¬¥)ÄkBHÕ‘FÕ¡Æ ‘¨k„Hm45‰µŠTÆpì6ÜHfl<Ðú€-: ÙÅ™’\Áœ‚l @ãà6f˜ pŒ [GrŒ‰DDÇuœ®ÿÎ茤Išúˆ"¼°‹Ä£µd‹,”ÊÔlzŸ•K«>Û¿ó° Ž¨¿j¤¼ðÂ/¬Ê¤8˜DÃñ"Œ~B&¯œÂ°KeˆÌ²T¿³ÔÇ´lˆÎ¨dqÊýAŠÕ9¿>ùHÁ"9¯9Z&;ÑA J+ÆlÊÁô«2Ì©ü3›¹JÀl̦zLšâ9d†ÉT[¨ÌËľÌ<¥T¼«Ðñ"âÂß艔‹1•B\Ÿ‹¨å:Ì9¿Ÿ8…J@ÇÊT†6ªËy ´L ûC±ÅAÀ¼ˆÇBD 3Š˜zÛ‹òECs?|Ÿçüg™Gg©N¹NâÙ>ÙŠBŒ(Å*„ Ïÿñ$ÏS0ÎrDO¿XOöL‹÷\¿ø¬Nš\CÕáŠH¬IÑOi:÷óψн¤è<œéŒFë¤í˜qÐ÷é$ÿñ4ó‘ôl£ =Ï =5\P0æ<<?ÝÀI`Øøšú¢ì̵‚Ek:4:œÈÇ 5NóŒ‰Jp.S0xòP*Õ8¿ÍA¤ÇúÐÒé"a:+Œb«çcQ!‹jr¯ÁÔ…™ˆÒ\ã&5½+z B SáQ. dšÌÊ$Ró!Sõ3Ó3u†ézÄusJ7uAzÙŽ™S\ùiJŠ(ÉÓýâ&õS@e$AM±*­Ó+ETOm–mTfxTÊ<¿ Ôÿé˜%Õ˜(ÐÚìÂæ¢/!Ì.ŒÏøKj:µœÑ™XAi=¿‹?d§¤z¼T–Ê ¢HÏ¿¨6‰k1+)©9(¡–D\Ÿ<¤Ñ¯¡Që³dMV\V‘¤PéÔCù«Vcý ÊVm ?±œo¥ ?ߨމ™RB•’:5´Gq®5 ÖLÖxX³bÄdýŒ{mVi.h•Gi¥‰TÜ@Œ¸V Â;€WĆؘViUÁEcK|E?£RIš* †Šà .„Ò(ʼn›²yŽÎ¤K\h ·\Ù€KÑüeàICkͨô³;"HàK0Q¢yŒY<Ùà¨Yÿø<@?ƒ–õcˆž…Í•ãˆßÀ ƒÙ¢u–^ðÔ‰a‹F“ÃtÚ§ÝÔÙPÅûŸÕQÔO-Èw„–:“”¯u†°…ÙܘY³e ´õAµ½&¶¥–,ùYh‘ÛÕùSy T¼½&½Ý)¦±=Yó‘ZÖU?µ‚O¼„²Çp1j¡+Q+=óTyô]—H¹½Ñ±ÝÕ´ÂÍ} è|]®X^³Â£ˆÊdLQU]\×E¹¸¢–\™KyÔªŽJR1’=?»­[Ä¡U‹!@nPª›…EÂÍd^æ}À#Íh‰^£Ð×ö«^Jñݲ%Ü‘¼æÍ‘î}Ðó ÝðU?÷ÅÝòu–ÿó¢Uß³&k2—•[ÌÌ!^ÎÃM¹•‘Œ@¹h‚{éˆyì…á†qJyëC¹‰y {Y4A:ö‹¯8PçÅ£¤QµkB5j@¹H‚I]@v•Ûá곎õ›¯^Lá}iD}Wâ€âæJ#¬ i¨öëá†hJˆ# ðÈJèØ âàÀðà%ÞüÁPƒ×… /Œ¨¤á” âÂÖý}Ñ_â:iÓà ÓJÀDƒ&Z”†„ˆ‰& ÒÙ+&Ÿ ™†¢P ã^£1Dœ†{éc?éãX!•Y(…xÁ—N‘¾Ufœ Ñ…{1•p8âÃHCÿG†+mâIa²À¥Š#@LîBœÈ œˆY¹P’ËcÁ{y Rö!•VŽ ÁD`€]Y€@ØÝ5eäFN—]Y ,9kkPÁ=æØè ÷èËIÕNÆàâói¯#³®¨X*e_õ+9g äŠè™x¼‰^Þ`¿9T«j”‘² 9LÏØ>æ”_°$T£åòXe Y„E˜åR®¦\鹸ˆƒKD† øÝÖy |ÞÝ™…Ö˜ ÷(Pw6 žf®hŠú§NÁ¶E€º>ÈgZ›³?ˆºˆé°rcš¦!džšøÜ˜F ªçžºg™‚’S=àŠ‰¯E³¦ÿ\8¹ƒ˜Š›(Y]Ѓ.©N?Ñæú˜Úµz+™JÏø ¾ô R¡>RêZ¨…Ïð_À´¨R©¦=é¸Hi©ÜÅ;š2 ž7Nü8“ eø‰ª±iyô‰?E@¾‰4bŸD¥fžÊ½†Û†˜…¿Æ£i „¹à2`2ȹè#ç•¢¹0J Q¸‚ ¸ì ŽÍþSœhkÎí]aô° iØêMêê˜j®#ýT5hv±Y•¹†˜‹7 ÖÔ…ª™jp„¹@&‰@65Ô¿ÙüÔkMS Ñ/Kº3£åY¨À^†Eèïλhl¸xl<›/|m1´]˜RKCÿŒôJ(EYö(ïó„ždîÞ0T«E톨oûvXU›†`‹;Žÿ 0J‰øÏ­0ñ¸ ŽXðD‹5P¶È”pe£ðªQî ¼p nöΈéÖ ®®)\‰°6׈IükOû¦›@ë²]’9Io9úärÂTЄ’H„DЄDè„W%¬ðo¶àÙ¿LJÐßV?@„HtˆYà\@ 2U«\(ð”8ƒŸ^ò¢Â(O Pî¸\ºâÔ†Sp„GôQ ðÙPfÜÀé#Ù ¹8»Ö¥ kQ*5·Yghó=J !àÖÎó=Oc¸ˆŽ˜Ø† xyòÎH‹Ú ¿7@/[ÈŠ²=èqK/PeØ ÁæÎ&9ä F¯öYߦÈ^4µhˆÕˆˆ\ r¹ƒ“Õ†aŸ?j`‘Yœ¼x¾.8€Z ‚[‡‘µ±QnZ¡8kö“߸æ1pæhˆ ÀP‹ùÂ@0{ƒVȃ}AèÐΉñ‹pc ïâ`j!òx˜±Iµ½©¹H{deqˆ&‹€ nˆ‹˜oi/… ˆ MøQYmmŸNŒÍ A–dA^LJÿv{Æ0çmÞ›úÂX‰Ï‹,Ïk ƒ¤‚¤ƒ(‚$€z)и~¯¥†@ˆº=H¥špºpaKÐ|O 2ˆ+9ÀŽ ¸¶i@Ï\,p:6(o  Ù¨„­)Yá@m¤2|Móˆ_Ö&Àeù¸xõDÔ’’Gñ-ª ˆ‹,HޤàÝ“µ ›Ö žð ºŠÌç_À4rÈ‘zâÁøu]‹ÕøŠ´˜…ý:po­3Ør¹-á¨+¢åˆÊ€:°†ñZj {8ƒ½éá– &8°Rh}gh#pЩçyÓ§aæ¯Kf¶5mR ½‘¯·€ å÷ÿPz±ȧŸ–4}¾Aþ¯÷±ZU–¡;p}>jéš4ƒÀ­ü®›†ðZC¼ÙàxÚ‹FBùhc‚”{a¬ÁµÅª/Ú‰À£¢ ÍfÑp„ÚØ6.\È&ø»ªr8…$T¼C^Bƒ âg¸¢H(€¥@&ÈÈM˜ 0¿ðE 4I†˜fñ­øÀÈ(C{ÎVtˆ@µôâS"aŽ[š¦–R…äTo”`ƒ*ˆAZír¸±Æ•9ƒ „&G¸އšhâ.R$7žn$r‘[Já#ÛIò¨’š㸂X¤!" U(iZ…&ÈDmÌÏUuê‹B¶…“ qƒaÿ+Éb4ÎT&›i'ƒxʺ0N] À?• H%Nq Œ£d¡„œ«n! QxÁ §@ÈÃ9Îd¶š¥wAoÌd(ËNprù¸8:Ò2ÐjZs tIBLAmz&J8 ORh—¹çA\õªexAxäH¢Rz+¬„Ú©K8`A“ p3›Ü¨MŠCÌ-$œâìâIb™’(ƒ£%Ú@¼¡Ìi16ÖÂM•DAæ±Ê–Ø;Š·¤ˆ½¾Dã¥9ƒIPå–æàâœ*K¤P ªÐµ >@§*£aˆ§\`]E_HŒÐ pÌg)[ ‡Q*’ˆ5C¹ ó{º Š%5&éR—6H4`1 M°‰ƒ…R5ÿÀ!(A×'æíÈ@ 1ep‡;AÝJJ-5F¡_ò@…;"Soèëo`î…&’70O» $M21ÞhâoÀMË䄳xÊó%£ë‹Õ8qQ¥Yò@Á<`$+¹BÌCFþˆ$Ã’."Ö2—»ÌA9.Šh?® ‘‹ U %¹P†)X †Ã'z)®q-( ·O9šžÙŒf\÷`6•±ÄTe A¿“‰†ER*©õe´Ê)èÁƒÒ¤%urú”4ì…[¹€4®qZA¤ÓÝr–a[Ý`†4J–JÜ8‡û»œk8dšE0ÄVoãÿjXÏzÖfþÒ8n»zBm ¶2è]ìwß!À1H›â“jê`‚­­LNk ¦V¶Ö‹8ÄÁ¡ïnë߇3Šqb‹ãxâ8"]ºqD”›ÆK²ÒÕ‚Q ¡¤Ì „Žð‚¨à oHÐJ·æq}/7¹!î@Dq‡7@a*HA VÀ2AÏèn‰ÏÊ”Ÿü6*_ùÉk½À\æâ¯3nŽsûÙø„ÞP…Lýop>Qt¹ Y•ÜÒ'qfpÞÞݸ·’ò¾u·A®z³ûx°ôÜ¢g€ƒ l ÈPsén+»oï-†ØÓÀÿÜà.pAÒ0Lþæ9¿nÆ}~˜ýóCŸ<åg»„­µ•Òš.É›<÷PšÔ‚'þ®^xŸHùíÇñ”w]º$Q*|x1n¹ËÞ)'] ›6tƒ4 ]Ø_…pÐÜňéÕ jÁÊ2ŒIA¨Ç“L|8R¢©­•ƨ sÅËEÉúIüÁŸû]Ãå_§ijþuZ¶LÍpQ…ÿe4à 4TH VÞA,`Q•^ QÉ Eà˜üÆ µGETÉ™d  Õ’ßžß©_¹q º_ ¢ ü­à ¶à Ò_ ÿUD >ÓÈU•Ò0È…HœµáþìÆ¶ÿø†pÝá *Iйàç ‹åáÆp9w°R…tÃ’é!‹”QÁ™¶üü T=bmß/°c`DQ !¬Å–(æªÈáåÔá@ Ñ)æ¡úa3ô¡záu¥âu b.°}^ê!Ó<“QÉä`θX$ª%aì\âz°K#Á[/~">ãøÅa¹Ñ!·Ø!§qš"¢Ðµ¢õý¡uѧ͢pÕâA¤!3@I8™ólf`TrßBœB1Èc1Ø"L„#¬åŸþ7ºb4iWvš4ÑØóac6* 34Ñí"¸IÎiT•PÆ·PDÇ•RE`"c€Kƒ(J“ÿè‚:z¹£;þ<ÊÓ<âš=zôÍŸ"þö¡ÖEƒ- ,mW’… d…pžBB_ƒå^¢ÀÈÌDÆ‘ÂX¤E`Sv G¦#­£H6IRN<žd=¾„JvKî#?ÂdLfXžbƒÙÅ„ä\8šã­ÚþÔÙªÕp,Ã) G=ò]Ôœb8þ! ^ƒö¤*RP“±\÷qЄ  Nî"±åã’dÞ…ìRcYIÀØJ×$ÅÑÝ4£Au`võž#Ä[Æ%JÒe*d±UÈu5ƒ ö¤šœv±\9] qaaFÓ¬``6£4fìÌdªždf eÞ'^¦C²e[DgÿÊeNèE]¾¦æ+š¦ 2œVùå¬eÒ¨Ý$l¢%ñX‹¥ô^ïQF Ée5ä{Ø!w^C78çõÁÒlªâ·)‰]Úå&Y|`ÓìâB.Ù@°fÌMXäaVf)EO¸,RU%»Dw–CÖÕ2ˆ'yVæ5äÂu z:§V."|Þçm€ã`â h~ê§O*œ“¨UôàÅ(©žŸ=Dåx Œ2(1ÊL-xg„ÒÕ„–B1Œ'®•ç)b(zÒßz²d‡^Ÿ²š|Š(*b‹ªhçvâw<‚ä¾i Eð]5`‹‰ƒ+*é°©âVÑ·]Œ’&–Ôeä# ÿ^è«-åB×Ý…ÀHQalKŒ\ྕzČƸœRUJ } ]]iªÈˆól)ÕX¡^€)]ˆizzaáé" þ ­éIÐXH&©`—%¢\\)äLÉ@ô„o0àžVôÕ Vä÷ø(¢V…¢òü ÖÔt)ßIª6Pª†Zª>²˜uiªšÎ‹1ÐHø©n„ÒV-†Eò7EM]Ä\7þ‘n#±kîg,ÎÅÒ Í’¦œ²¤ŽD•`ÎÇ•ÕD¾ èii W]†•Æ„=ŽÚ`Ek¬8ÄÌŠ|L¶’f&‘^æ  ª ,Ù ¬-$VàÏ܆uuYþ¹{i"pÿ0Pn–R/ÂŒ>¦½ÂÌp‡b\g§´lÀ²ßÀ†¶¦çÁ tn#öÚ3í"8Fi³6«ªPF—F69Ñ}ºäit¢+·*Iáɇ,Ö˜:Ív-ɤ¹&¥­9bˆE^¤o\ÄÅÝì’ÌŒí·ÖÓ ìþ /Î]J­”-b%íý^ÓÒ‹å-±]ËhJ“,&O“a­Ô’hÃêg—Ù#NÅåLS åQ¢-NÕ…¬­A -Üí£bdB ­’(m™&l±>íýMˆ@üíÚ^£àþ,ÐÙ8\Õ^fE4–Æ€dê3t ýA',]*·~ëA.]Ãÿ2Q(Å"®U‹å##¢!£EŽ¥ŒXšÐHgI½Ä¿nìÊ..ЮÆn8æîç™&½‰¡ivšðrë°* FÑ4ïÚÅÒ`ÔÃòâ@Ä„Æê†)M¯7ToeÆ'k¯v¯þ'…¯žÖ.ù^Wî úòîñ¬ïï «*¯ D…°.U¹.Áî=ê_œXÏLz¬qÞçþ¥oð~ë¤]íZ#/ní`"à…†©œ²×Ùj1Z Ÿj̸LPEäÕ™LÚnY.ZH]¤Wµ­nŽ …_ÔY k%3ô¡ —fÓêe™r0N¡ëˆZgˆ]’EŒœÂ„Îu¨9¨>bŒ¬ªO×–\ü:±"¦­ëê¢V1pŽ k±¸²p’V0“¦Æ‘ñX¾bh~Ê÷U2SK%g²&o2'w²'2(‡²(2)—²)Ÿ2*§²*¯2+·òð\2Ò¸²,Ï2-ײ-ß2.ç².ïò)aÃ23ñ20³031³1³/ƒð1/337³3?34×r2O35W³5_36g³6o37w³738‡³839—³9Ÿ3:§³:¯3;·³;¿3<dz<Ï3=׳=ß3>ç³>Ïs@;haskell98-report-20080907/report/classes.ppt0000644000175000017500000007400011345221573020137 0ustar marcotmarcotÐÏࡱá>þÿ þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿ9 þÿÿÿþÿÿÿ: !"#$%&'()*+,-./012345678þÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot Entryÿÿÿÿÿÿÿÿd›Oφꪹ)è X‚r›êÁ€PowerPoint Document(ÿÿÿÿ4$SummaryInformation(ÿÿÿÿÿÿÿÿ¨BDocumentSummaryInformation8ÿÿÿÿÿÿÿÿÿÿÿÿèèé(ó ¸p ò`/È 0ÒÕ˜·DTimes New Romanü·ä·ô» 0ü·‹Ê 0ô··DCourier Newmanü·ä·ô» 0ü·‹Ê 0ô·1¤€@ÿÿ¥ .©  @£nÿý?" dd@ÿÿïÿÿÿÿÿÿ  @@``€€ ˆð€ð($!ƒ ð0ƒ†A¿ÀÅAÿ@ñ÷ðó€Ðmÿ úgþý4LdLd¸‹Ê 0fúÿÿ¦ÿÿÿpû pûúº“°öÊš;­”ÇÊš;<ý4dddd@¸@v 0,¸ˆrŠ0º___PPT10‹ pµpµŠ2º___PPT9‹/È 0Ò?Ù Ú%ðóêøœ ï `ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²²`ð ÿÿÿÿÿÿÿ™ÿÿÿ–––`ð ÿÿÌff3€€3™3€3ÌÿÌf`ð ÿÿÿ333ÝÝÝ€€€MMMêêê`ð ÿÿÿ€€€ÿÌfÿÌÌÀÀÀ`ð ÿÿÿ€€€ÀÀÀfÿÿ™`ð ÿÿÿ€€€3™ÿ™ÿÌÌ̲²²£>ÿý?" ddÓÿÿïÿÿÿÿÿÿ$£|ÿý?" dd¯Óÿÿïÿÿÿÿÿÿ€ |ê€" HÓ€ 2½€»§ £nÿý?" dd@ÿÿïÿÿÿÿÿÿ   @@``€€P£R  ê Ó ½ §`£ p£>€£>   Æð¾ ððVð( ðõõõõõõõõõõõõõõõõ ððð ð ã ðT€‚žÒ!‚éƒÒ!„釿ƒ¿Àÿ ð™ ç šðà ž ðTŸ¨ Click to edit Master title style¢!ª !ð4 ð Ó ðN€(…žÒ!‚éƒÒ!„鿃¿Àÿ ð4 ç ðà ž 𞟨RClick to edit Master text styles Second level Third level Fourth level Fifth level¢!    ª Sðò ð Ó ðN€8’žÒ!‚éƒÒ!„鿃¿Àÿ ðg ôšðà ž ð\Ÿ *¡ ø¦ñÓêêÓÓ½½§§ðô ð Ó ðN€€•žÒ!‚éƒÒ!„鿃¿Àÿ ðgÄ/ šðà  ž ð^Ÿ *¡ ú¦ñÓêêÓÓ½½§§ðô ð Ó ðN€ÐŸžÒ!‚éƒÒ!„鿃¿Àÿ ðgÿ ç šðà ž ð^Ÿ *¡ ئñÓêêÓÓ½½§§ðH ð ƒ ð0ƒ“1™V”ηo¿ÿ ?ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²² º,Blank Presentation.potîCï€ óðëð ðÛð( ðû¤*(d~ð` ððæ2 ð “ ð6€LÕž…‡ÿÌÌ¿ÀËœ1ÿðbdÓ) ð€Ÿ¨Eq All except IO, (->)¡4 ªð2 ð “ ð6€DÜž…‡ÿÌÌ¿ÀËœ1ÿðâdþ² 𜟨 Ord All except (->) IO, IOError¡4! ª$ðþ2 ð £ ð<€Ôâž…‡ƒ¿ÀËœ1ÿðäu ± 𒟨 Num Int, Integer, Float, Double¡4! ªð^ ð “ ð6…‡ÿf¿ÀÑÿð)1âðX ð ƒ ð0…‡¿ÀÑÿð)DäðÆ2 ð “ ð6€Têž…‡ÿÌ¿ÀËœ1ÿðn Ê ð`Ÿ¨Show All except IO, (->)¡, ðÿ2 ð £ ð<€¬ðž…‡ƒ¿ÀËœ1ÿð«hÙ` 𓟨!Real Int, Integer, Float, Double¡4" ªðÔ2 ð  £ ð<€˜÷ž…‡ƒ¿ÀËœ1ÿð° ¹ [ ðhŸ¨Fractional Float, Double¡4   ð.2 ð  “ ð6€D…‡ÿÿ¿ÀËœ1ÿð` *ª ðÈŸ¨:Enum (), Bool, Char, Ordering, Int, Integer, Float, Double¡4;5 ª6ðì2 ð  £ ð<€ …‡ƒ¿ÀËœ1ÿð€ zy'  ð€Ÿ¨RealFrac Float, Double¡4  ªðÒ2 ð  £ ð<€” …‡ƒ¿ÀËœ1ÿð€ Æ '  ðfŸ¨Floating Float, Double¡4  ðó2 ð  £ ð<€<…‡ƒ¿ÀËœ1ÿð€ '  ð‡Ÿ¨Integral Int, Integer¡4  ª  ðí2 ð £ ð<€è…‡ƒ¿ÀËœ1ÿðæ „ú f  ðŸ¨RealFloat Float, Double¡4   ª ðX ð ƒ ð0…‡¿ÀÑÿð5DäðX ð ƒ ð0…‡¿ÀÑÿð²1!«ðX ð@ ƒ ð0…‡¿ÀÑÿð±!D«ðX ð@ ƒ ð0…‡¿ÀÑÿð`‰!€ ðX ð@ ƒ ð0…‡¿ÀÑÿð`ú!€ ðX ð@ ƒ ð0…‡¿ÀÑÿð[o æ € ðX ð@ ƒ ð0…‡¿ÀÑÿð[úæ € ðX ð@ ƒ ð0…‡¿ÀÑÿð' ?n æ ðX ð ƒ ð0…‡¿ÀÑÿð' ú?æ ðX ð ƒ ð0…‡¿ÀÑÿðª%‰€ ðÎ2 ð “ ð6€ô…‡ÿÌ¿ÀËœ1ÿðaƒ  ) ðhŸ¨Read All except IO, (->)¡4 ð(2 ð “ ð6€h&…‡ÿÿ¿ÀËœ1ÿðÀ Ø Õ ðŸ¨,Bounded Int, Char, Bool, () Ordering, tuples¡4-$ ª>ðÉ2 ð “ ð6€Ä-…‡¿ÀËœ1ÿðÙŒÝ ðcŸ¨Monad IO, [], Maybe¡4  ðÝ2 ð “ ð6€X9…‡¿ÀËœ1ÿðÙÜ- ~ ðwŸ¨Functor IO, [], Maybe¡, ªðX ð ƒ ð0…‡¿ÀÑÿð±Dæ °ð^" ð  “ ð6…‡ƒ¿ÀËœ1ÿððÀP @ðH ð ƒ ð0ƒ“1™V”ηo¿ÿ ?ßð ðððððð ð ð  ð  ð ð ð  ð ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²²r0 ­ õ² ø#âþÿÿÿ þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÕÍÕœ.“—+,ù®0¸ˆ ¬´¼Ä Ì ÔÜ äìôü  WäCustom st4$&­ Times New Roman Courier NewBlank Presentation.potSlide 1  Fonts UsedDesign Template Slide Titlesþÿà…ŸòùOh«‘+'³Ù0xB hpˆ¤ð  4 @ LX`äNo Slide TitleSimon Peyton JonesCC:\Program Files\Microsoft Office\Templates\Blank Presentation.pot Peyton Jonesles5ytMicrosoft PowerPointoso@àÿ‰~Š@ év ù¾@Pïrr›êÁ>GAÿÿÿÿÑ ‰  Î  éüÿÿÿ-úÿÿÿ- @ !ðéÿÿÿÿú-üÿÿÿ-'ÿÿú-ü-Š%C¬L¢M™MO‡PRwUpXi[c^]bXfTkQoOtMyM~MƒOˆQŒT‘X•]™ci¡p¤w§©‡«­™®¢¯¬¯¶¯¿®É­Ñ«Ú©â§é¤ð¡öû™•‘Œ ˆ ƒ € ~ { y tokfûbö^ð[éXâUÚRÑPÉO¿M¶M¬L--ð'ÿÿûäÿ¼@1Courier New-.  2 zœEq.û¼"System³ä-ðûëÿ@Times New Roman-. 2 –^All except IO, ( .-ðûëÿ@Times New Roman-.  2 –à-û.-ðûëÿ@Times New Roman-.  2 –ç>) .-ðú--Ž%E±×§ØØ“ÚŠÛÝyàqãjædê^íYòUöQûOÿMMM M MOQUY"^&d*j-q0y36Š8“:;§<±<»<Å;Ï:Ø8á6é3ñ0ø-þ*& "   ÿû ö òíþêøæñãéàáÝØÛÏÚÅØ»Ø±×--ð'ÿÿûäÿ¼@1Courier New-.  2 ú˜Ord.-ðûëÿ@Times New Roman-. 2 s All except ( .-ðûëÿ@Times New Roman-.  2 Õ-û.-ðûëÿ@Times New Roman-.  2 Ü>) .-ðûëÿ@Times New Roman-. 2 /}IO, o.-ðûëÿ@Times New Roman-. 2 /¢IOError   .-ðú--–%I“؉ØÙuÚlÜcÞ[àSãLæFê@î;ò7ö3û10/// / /0137;"@&F*L-S0[3c6l8u9;‰;“<ž;§;±9º8Ã6Ë3Ó0Ú-á*ç&ì"ðóö÷÷ø ø ø÷÷öóûðöìòçîáêÚæÓãËàÃÞºܱڧٞؓØ--ð'ÿÿûäÿ¼@1Courier New-.  2 úzNum.-ðûëÿ@Times New Roman-.  2 `Int .-ðûëÿ@Times New Roman-. 2 v , Integer,   .-ðûëÿ@Times New Roman-. 2 /Z Float, Double    .-ððú-ü-&8 ­¯±Ò±Ò°Ò°Ò°Ò¬¯¬¯¬®­¯­¯­¯µÌ±×«ÎµÌ--ð'ÿÿú--&8 ¬®ŽÖŽÖŽ׎׎׬°¬°¬¯¬¯¬®¬®ŠÑ“؈ÛŠÑ--ð'ÿÿú--†%AO‡O~PvQnSfU_WXZR]L`GdCh?l<p:t9y8~9ƒ:‡<Œ?C”G˜LœRŸX¢_¥f§n©v«~¬‡¬­™¬¢¬ª«²©º§Á¥È¢ÎŸÔœÙ˜Ý”áäŒæ‡çƒè~çyætäpálÝhÙdÔ`Î]ÈZÁWºU²SªQ¢P™OO--ð'ÿÿûäÿ¼@1Courier New-.  2 noShow.-ðûëÿ@Times New Roman-. 2 Še All except .-ðûëÿ@Times New Roman-. 2 £pIO, (o.-ðûëÿ@Times New Roman-.  2 £–-û.-ðûëÿ@Times New Roman-.  2 £>) .-ðú--Ž%EŒr‚rxsotfv^xVzO}H€Bƒ<‡7‹30“.˜,,Ÿ,¡,¤,¦.«0°3´7¸<¼BÀHÃOÆVÉ^ËfÍoÏxЂьѕџШϱ͹ËÁÉÈÆÏÃÕÀÛ¼à¸ä´ç°é«ë¦ë¤ë¡ëŸëé˜ç“äà‹Û‡ÕƒÏ€È}Áz¹x±v¨tŸs•rŒr--ð'ÿÿûäÿ¼@1Courier New-.  2 ’jReal.-ðûëÿ@Times New Roman-.  2 ®XInt .-ðûëÿ@Times New Roman-. 2 ®n , Integer,   .-ðûëÿ@Times New Roman-. 2 ÇS Float, Double    .-ðú--–%I]sSsIt?u5w-y${~„ ˆ‹ÿü”ú˜ùšøøŸ÷¡ø¤ø¦ù¨ú«ü¯ÿ³¸ »¿ÂÅ$È-Ê5Ì?ÎIÏSÐ]ÐgÐqÏ{΄ÌÊ–Èť«¿±»¶¸º³¾¯À«Á¨Â¦Â¤Â¡ÂŸÂÁšÀ˜¾”º¶‹±ˆ«„¥~–{y„w{uqtgs]s--ð'ÿÿûäÿ¼@1Courier New-. 2 ž  Fractional.-ðûëÿ@Times New Roman-. 2 º$ Float, Double    .-ðú--¦%Q®b£b˜ceƒgyipmgp_tXyQ~LƒG‰E‹CŽB‘@”?˜?›>ž>¡>¥?¨?«@®B±C´E·GºLÀQÅXÊ_ÎgÒpÖyÙƒÜÞ˜à£á®áºáÅàÐÞÚÜäÙíÖöÒþÎÊ ÅÀº·´±®«¨¥¡ž›˜”‘Ž‹‰ƒ ~yþtöpímäiÚgÐeÅcºb®b--ð'ÿÿûäÿ¼@1Courier New-.  2 …Enum.-ðûëÿ@Times New Roman-.  2 ¡G(), .-ðûëÿ@Times New Roman-.  2 ¡_Bool .-ðûëÿ@Times New Roman-. !2 ¡‰, Char, Ordering,   .-ðûëÿ@Times New Roman-.  2 ºcInt .-ðûëÿ@Times New Roman-. !2 ºy, Integer, Float,    .-ðûëÿ@Times New Roman-. 2 ÓDouble  .-ðú--†%Aƒ{rjc[UNHC >$:'6+4024090=0B2F4K6O:S>WCZH^NaUc[fchjirj{kƒkŒk”jœi£h«f²c¸a¾^ÃZÈWÌSÐOÓKÕFÖBÖ=Ö9Õ4Ó0Ð+Ì'È$à ¾¸²«£œ”Œƒ--ð'ÿÿûäÿ¼@1Courier New-. 2 :ARealFrac.-ðûëÿ@Times New Roman-. 2 VJ Float, Double    .-ðú--†%AC:1( ü ÷$ò'î+ë0é4ç9ç=çBéFëKîOòS÷WüZ^ acfh(i1j:kCkMkVj_ighofwc~a„^ŠZW”S˜O›KFŸBŸ=Ÿ94›0˜+”'$Š „~wog_VMC--ð'ÿÿûäÿ¼@1Courier New-. 2 :Floating.-ðûëÿ@Times New Roman-. 2 V  Float, Double    .-ðú--†%AÄ»³«¤–Š… €$|'x+v0t4r9r=rBtFvKxO|S€W…ZŠ^a–cf¤h«i³j»kÄkÌkÔjÜiähëfòcøaþ^ZW SOKFB=940+ '$ þøòëäÜÔÌÄ--ð'ÿÿûäÿ¼@1Courier New-. 2 :‚Integral.-ðûëÿ@Times New Roman-.  2 V–Int .-ðûëÿ@Times New Roman-. 2 V¬ , Integeru  .-ðú--Ž%EÊ•À•¶•­–¤˜œš”œž†¡¤z§uªq®n²k¶jºj¼j¾jÀjÃkÇnËqÎuÒzÖÙ†ÜÞ”áœã¤å­æ¶çÀèÊèÔèÝçææïåøãÿáÞÜÙÖÒ"Î&Ë(Ç)Ã*À*¾*¼)º(¶&²"®ª§¤¡žÿœøšï˜æ–ݕԕʕ--ð'ÿÿûäÿ¼@1Courier New-. 2 » RealFloatu.-ðûëÿ@Times New Roman-. 2 ב Float, Double    .-ðú--&8 ‘­“Ò“Ó“Ó’Ó’Ò­¬¬¬‘­‘­˜Í“ØΘÍ--ð'ÿÿú--&8 ±;†p‡p‡q‡q†q±=°<°<±;±;±;ƒjŒr€uƒj--ð'ÿÿú--&8 ”<lmŒmŒmŒl“<“;“;”;”<”<’hŒrˆg’h--ð'ÿÿú--&8 ŒÑÊÉÉÉ É ‹ÐŒÐŒÑŒÑŒÑŒÑÏÄÌÏ--ð'ÿÿú--&8 ŒÑ… „ „ ƒ ƒ ‹Ñ‹ÐŒÐŒÐŒÑŒÑŠƒŠ--ð'ÿÿú--&8 ^ÐF F E E E \Ð]Ï]Ï^Ï^Ð^ÐLCBL--ð'ÿÿú--&8 ]Љˆˆˆ ˆ ]Ï]Ï^Ð^Ð]Ð]ЃŒ--ð'ÿÿú--&8 ClϓϓΓΒϒCkCkDkDkClClՖʕҌՖ--ð'ÿÿú--&8 ƒkőŒŒŒŒƒlƒkƒkƒkƒkƒkËʕ¾”Ë--ð'ÿÿú--&8 ¯á   Á Á ®á®á®à¯à¯á¯áÄÄ»Ä--ð'ÿÿú--†%AXLPLIMBN<P6R0U*W%[ ^bfjoty~ƒˆŒ‘•™ %¡*¤0§6©<«B­I®P¯X¯_¯f®m­t«z©€§…¤Š¡“™—•š‘œŒžˆŸƒŸ~Ÿyžtœošj—f“b^Š[…W€UzRtPmNfM_LXL--ð'ÿÿûäÿ¼@1Courier New-.  2 n7Read.-ðûëÿ@Times New Roman-. 2 Š- All except .-ðûëÿ@Times New Roman-. 2 £8IO, (r.-ðûëÿ@Times New Roman-.  2 £^-û.-ðûëÿ@Times New Roman-.  2 £e>) .-ðú--†%AnÐeÐ\ÑSÒKÔC×;Ú4Ý.á(å"éîóùþ  %"*(..346;:C=K?SA\BeCnDwC€B‰A‘?™=¡:¨6®3´.º*¾% ÅÇÉÉ ÉÇþÅùÂó¾îºé´å®á¨Ý¡Ú™בÔ‰Ò€ÑwÐnÐ--ð'ÿÿûäÿ¼@1Courier New-. 2 ú4Boundedl.-ðûëÿ@Times New Roman-.  2 $Int .-ðûëÿ@Times New Roman-. 2 :, Char,  .-ðûëÿ@Times New Roman-.  2 xBool .-ðûëÿ@Times New Roman-.  2 ¢, ().-ðûëÿ@Times New Roman-. 2 /+ Ordering,   .-ðûëÿ@Times New Roman-. 2 /€tuples  .-ðú--†%Aé8à9×9Î:Å<½>¶@¯C¨F¢IM˜P”T‘Y]bfko‘t”x˜|€¢ƒ¨‡¯Š¶Œ½ŽÅÎ’דà”é”ó”ü“’ ŽŒ$Š*‡0ƒ6€:|>xAtCoEkEfEbC]AY>T:P6M0I*F$C@> <:ü9ó9é8--ð'ÿÿûäÿ¼@1Courier New-. 2 cÀMonads.-ðûëÿ@Times New Roman-. 2 ° IO, [], Maybe .-ðú--†%A89þ9õ:ì<ä>Ý@ÖCÏFÉIÄM¿P»T¸Y¶]µa´fµk¶o¸t»x¿|ĀɃφ։݌äŽìõ’þ“”””#“,’4<ŽDŒK‰Q†Wƒ]€a|exhtkolklflak]hYeTaP]MWIQFKCD@<>4<,:#998--ð'ÿÿûäÿ¼@1Courier New-. 2 cÖFunctor .-ðûëÿ@Times New Roman-. 2 Ø IO, [], Maybe .-ðú--&8 “;XqXqXrXrWr“<“<“<“;“;“;Tk]sRuTk--ð'ÿÿú--Î%ež4˜4’4Œ5†6€7{9v;p=fB]HTNKVD^=g7q2{0€.…-‹,‘+–*œ)¢)¨)J)P*U+[,a-g.l0r2w7=‹D”KœT£]ªf°pµv·{¹€º†¼Œ½’½˜¾ž¾o¾u¾{½½†¼Œº‘¹—·œµ¦°°ª¹£ÁœÉ”Ï‹ÕÚwÜrÞlßgáaâ[ãUãPãJã¨ã¢ãœâ–á‘ߋޅ܀Ú{ÕqÏgÉ^ÁV¹N°H¦Bœ=—;‘9Œ7†65{4u4o4ž4--ð'ÿÿCurrent UserÿÿÿÿÿÿÿÿÿÿÿÿDÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö$_À‘ã$ ôžPeyton JonesPeyton Joneshaskell98-report-20080907/report/standard-prelude.verb0000644000175000017500000000653111345221573022077 0ustar marcotmarcot% % $Header: /home/cvs/root/haskell-report/report/standard-prelude.verb,v 1.4 2002/12/10 11:51:11 simonpj Exp $ % %**The Haskell 98 Report: Standard Prelude %**~header %*anchor on \section{Standard Prelude} \label{stdprelude} In this chapter the entire \Haskell{} Prelude is given. It constitutes a {\em specification} for the Prelude. Many of the definitions are written with clarity rather than efficiency in mind, and it is not required that the specification be implemented as shown here. The default method definitions, given with @class@ declarations, constitute a specification {\em only} of the default method. They do not constitute a specification of the meaning of the method in all instances. To take one particular example, the default method for @enumFrom@ in class @Enum@ will not work properly for types whose range exceeds that of @Int@ (because @fromEnum@ cannot map all values in the type to distinct @Int@ values). The Prelude shown here is organized into a root module, @Prelude@, and three sub-modules, @PreludeList@, @PreludeText@, and @PreludeIO@. This structure is purely presentational. An implementation is not required to use this organisation for the Prelude, nor are these three modules available for import separately. Only the exports of module @Prelude@ are significant. Some of these modules import Library modules, such as @Char@, @Monad@, @IO@, and @Numeric@. These modules are described fully in Part~\ref{libraries}. These imports are not, of course, part of the specification of the @Prelude@. That is, an implementation is free to import more, or less, of the Library modules, as it pleases. Primitives that are not definable in \Haskell{}, indicated by names starting with ``@prim@'', are defined in a system dependent manner in module @PreludeBuiltin@ and are not shown here. Instance declarations that simply bind primitives to class methods are omitted. Some of the more verbose instances with obvious functionality have been left out for the sake of brevity. Declarations for special types such as @Integer@, or @()@ are included in the Prelude for completeness even though the declaration may be incomplete or syntactically invalid. An ellipsis ``@...@'' is often used in places where the remainder of a definition cannot be given in Haskell. To reduce the occurrence of unexpected ambiguity errors, and to improve efficiency, a number of commonly-used functions over lists use the @Int@ type rather than using a more general numeric type, such as @Integral a@ or @Num a@. These functions are: @take@, @drop@, @!!@, @length@, @splitAt@, and @replicate@. The more general versions are given in the @List@ library, with the prefix ``@generic@''; for example @genericLength@. \clearpage % The index entries for :, [], (), and tuples are here % it just so HAPPENS that they'll end up referring to the right page % HHAACCKK!! <---- Partain, you scoundrel! -- KH % Well, they aren't there anymore so I nuked them. So there! jcp \inputHS{Prelude}\clearpage %\subsection{Prelude {\tt PreludeBuiltin}} %\label{preludebuiltin} %\input{PreludeBuiltin}\clearpage \subsection{Prelude {\tt PreludeList}} \label{preludelist} \inputHS{PreludeList}\clearpage \subsection{Prelude {\tt PreludeText}} \label{preludetext} \inputHS{PreludeText}\cleardoublepage \subsection{Prelude {\tt PreludeIO}} \label{preludeio} \inputHS{PreludeIO} %**~footer haskell98-report-20080907/report/haskell.verb0000644000175000017500000003271611345221573020270 0ustar marcotmarcot% Formatting for double-sided \documentclass[twoside,11pt]{book} \usepackage{times} \usepackage{makeidx} \usepackage{graphicx} \evensidemargin=0in \oddsidemargin=.5in \sloppy %--------------------------------------------------------------------- % Joe Fasel said this "twosidefix" is necessary if you really % have a two-sided printer: % (note: double @@'s for verbatim-ery) \makeatletter \def\titlepage{\@@restonecolfalse\if@@twocolumn\@@restonecoltrue\onecolumn \else \newpage \fi \thispagestyle{empty}\c@@page\m@@ne} \def\endtitlepage{\if@@twoside\newpage\thispagestyle{empty}\hbox{} \else \c@@page\@@z \fi \if@@restonecol\twocolumn \else \newpage \fi} \makeatother %--------------------------------------------------------------------- % the major sections have \cleardoublepages between them % if you want those between EVERY section, change the % following defn: \newcommand{\startnewsection}{\clearpage} % % if doing one-sided printing, change this defn to % be just "\clearpage": \newcommand{\startnewstuff}{\cleardoublepage} % keep some pages from looking unbelievably appalling \raggedbottom % Fix those ugly floating figures. \renewcommand{\floatpagefraction}{0.1} \renewcommand{\textfraction}{0.1} \renewcommand{\topfraction}{1.0} \renewcommand{\bottomfraction}{1.0} % table of contents: show only down to subsections \setcounter{tocdepth}{3} \setcounter{secnumdepth}{3} % general formatting \textheight=8.5in \textwidth=6.0in \topmargin=0in \pagestyle{headings} \makeindex % an extra thing for makeindex \newcommand{\hseealso}[2]{{\em see also\/} #1} % NEWCOMMANDS % general \newcommand{\folks}[1]{\begin{quote}\sf#1\end{quote}} \newcommand{\sectionpart}[1]{\vspace{2 ex}\noindent{\bf #1}} \newcommand{\bq}{\begin{quote}} \newcommand{\eq}{\end{quote}} \newcommand{\bt}{\begin{tabular}} \newcommand{\et}{\end{tabular}} \newcommand{\bto}{\begin{tabular}} \newcommand{\eto}{\end{tabular}} \newcommand{\bi}{\begin{itemize}} \newcommand{\ei}{\end{itemize}} \newcommand{\struthack}[1]{\rule{0pt}{#1}} \newcommand{\inputHS}[1]{{\small \input{#1}}} % Use smaller font \newcommand{\ToDo}[1]{} %\newcommand{\ToDo}[1]{({\bf $\spadesuit$ ToDo:} {\em #1})} \newcommand{\WeSay}[1]{} %\newcommand{\WeSay}[1]{({\bf $\clubsuit$ YaleSays:} {\em #1})} \newcommand{\anchor}[2]{#2} % indexing \newcommand{\indextt}[1]{\index{#1@@{\tt #1}}} \newcommand{\indexsyn}[1]{\index{#1@@{\it #1}}} \newcommand{\indexmodule}[1]{\index{#1@@{\tt #1} (module)}} \newcommand{\indextycon}[1]{\index{#1@@{\tt #1} (datatype)}} \newcommand{\indexsynonym}[1]{\index{#1@@{\tt #1} (type synonym)}} \newcommand{\indexclass}[1]{\index{#1@@{\tt #1} (class)}} \newcommand{\indexdi}[1]{\index{#1@@{\tt #1} (class)!derived instance}} \newcommand{\indexnote}[1]{#1n} \newcommand{\emptystr}{[\,]} \newcommand{\ignorehtml}[1]{#1} \makeatletter \def\theindex{\@@restonecoltrue\if@@twocolumn\@@restonecolfalse\fi \columnseprule \z@@ \columnsep 35pt\twocolumn[\section*{Index} \addcontentsline{toc}{section}{Index} \input{index-intro}\vskip 20pt] \@@mkboth{INDEX}{INDEX}\thispagestyle{plain}\parindent\z@@ \parskip\z@@ plus .3pt\relax\let\item\@@idxitem } \makeatother % outlined figures \newcommand{\ecaption}[1]{\vspace{-1 ex}\caption{#1}\vspace{1 ex}} \newcommand{\outline}[1]{% \begin{center} \fbox{ \begin{minipage}{415pt} \vspace{1 ex} #1 \end{minipage} } \vspace{1 ex} \end{center} } \newcommand{\outlinec}{\outline} % Centered outlines in html \newcommand{\bprog}{% \par\noindent\begin{tabular}{@@{\hspace*{17pt}}l@@{}}} \newcommand{\eprog}{% \end{tabular}\\[\parskip]} \newcommand{\eprogNoSkip}{% \end{tabular}} % % variants for stdprelude; don't indent, and skip a little more \newcommand{\bprogB}{% \begin{tabular}{@@{}l@@{}}} \newcommand{\eprogB}{% \end{tabular}\\[0.6\baselineskip]} %special characters \newcommand{\bkq}{\mbox{\tt \char'022}} % (syntax) backquote char \newcommand{\bkqB}{\bkq\hspace{-.2em}} % (syntax) backquote char (Before) \newcommand{\bkqA}{\hspace{-.2em}\bkq}% (syntax) backquote char (After) %\newcommand{\fwq}{\mbox{\it \char'023}} % (syntax) (forward) quote char % math formatting \newcommand{\ba}{\begin{array}} \newcommand{\ea}{\end{array}} \newcommand{\mc}{\multicolumn} \newcommand{\pile}[1]{\ba[t]{@@{}l@@{}} #1 \ea} \newcommand{\eqn}[1]{\ba[t]{@@{}lcl@@{}} #1 \ea} \newcommand{\equate}[1]{\[\eqn{#1}\]} \newcommand{\la}{\leftarrow} \newcommand{\ra}{\rightarrow} \newcommand{\sq}[1]{[\,#1\,]} \newcommand{\ab}[1]{\langle#1\rangle} \newcommand{\ablarge}[1]{\langle \pile{#1\,\rangle}} \newcommand{\lb}{[\![} \newcommand{\rb}{]\!]} \newcommand{\db}[1]{\lb#1\rb} \newcommand{\ti}[1]{\mbox{{\it #1}}} \newcommand{\tr}[1]{\mbox{{\rm #1}}} \newcommand{\tb}[1]{\mbox{{\bf #1}}} \newcommand{\x}{\times} \newcommand{\lam}{\lambda} \newcommand{\kr}{\kappa_{\rho}} \newcommand{\syneq}{\rightarrow} % denotational semantics \newcommand{\denote}[3]{\[\ba{c} {\cal #1} : #2 \\[1 ex] #3 \ea\]} \newcommand{\den}[2]{{\cal #1}\db{#2}\,} \newcommand{\A}{\den{A}} \newcommand{\B}{\den{B}} \newcommand{\D}{\den{D}} \newcommand{\E}{\den{E}} \newcommand{\F}{\den{F}} \newcommand{\G}{\den{G}} \newcommand{\I}{\den{I}} %%% \renewcommand{\L}{\den{L}} \newcommand{\LE}{\den{L_E}} \newcommand{\LH}{\den{L_H}} \newcommand{\M}{\den{M}} %%% \renewcommand{\O}{\den{O}} \renewcommand{\P}{\den{P}} \newcommand{\Pbot}{\den{P_{\bot}}} \newcommand{\Q}{\den{Q}} \newcommand{\R}{\den{R}} \renewcommand{\S}{\den{S}} \newcommand{\V}{\den{V}} \newcommand{\W}{\den{W}} \newcommand{\T}[2]{\den{T}{#1}\,\db{#2}} % meta language \newcommand{\PP}{\den{P'}} \newcommand{\PS}{\den{P_S}} \newcommand{\otherwise}{\quad\tr{otherwise}} \newcommand{\case}[2]{\pile{ \tr{case}\ (#1)\ \tr{of} \\ \ba{@@{\quad}l@@{\ \ra\ }l@@{}} #2 \ea}} \newcommand{\where}[2]{#1 \quad\tr{where}\quad #2} \newcommand{\wherelarge}[2]{\pile{#1 \\ \tr{where} \\ \eqn{#2}}} \newcommand{\cond}[3]{#1 \ra #2,\ #3} \newcommand{\condlarge}[1]{\ba[t]{@@{}l@@{\ \ra\ }l@@{}} #1 \ea} \newcommand{\range}[2]{{}_{#1}^{#2}\,} % semantic operators \newcommand{\concat}{\frown} \newcommand{\seq}[1]{\ti{List}\ #1} \newcommand{\opt}[1]{\widetilde{#1}} \newcommand{\ov}{\opt{v}} \newcommand{\fail}{\ti{none}} \newcommand{\nonfail}{\ti{proper}} \newcommand{\sym}{\bigtriangledown} \newcommand{\pri}{\mathbin{\vec{\sym}}} \newcommand{\mrg}{\mathbin{\dot{\sym}}} \newcommand{\Sym}{\mathbin{\nabla}} \newcommand{\Pri}{\mathbin{\vec{\Sym}}} \newcommand{\Mrg}{\mathbin{\dot{\Sym}}} \newcommand{\optSym}{\mathbin{\opt{\Sym}}} \newcommand{\optodot}{\mathbin{\opt{\odot}}} \newcommand{\proj}{\mid} \newcommand{\restrict}{\setminus} \newcommand{\sel}[4]{\ti{sel}_{#3#2}\ #4} \newcommand{\bindnone}{\ti{bindnone}} \newcommand{\bindvar}[2]{\ti{bindvar}\ \db{#1}\ #2} \newcommand{\bindcon}[2]{\ti{bindcon}\ \db{#1}\ #2} \newcommand{\bindconlarge}[4]{ #4\ \bindcon{#1}{\ablarge{ #2, \\ #3}}} \newcommand{\bindmod}[2]{\ti{bindmod}\ \db{#1}\ #2} \newcommand{\lookupval}[2]{\ti{lookupval}\ #1\ \db{#2}} %%% NEW \newcommand{\lookupcon}[1]{\ti{lookupcon}\ \db{#1}} %%% NEW \newcommand{\lookupdecon}[2]{\ti{lookupdecon}\ #1\ \db{#2}} %%% NEW % used in static.verb \newcommand{\TT}{\den{T_T}} \newcommand{\TA}{\den{T_A}} \newcommand{\TB}{\den{T_B}} \newcommand{\TD}{\den{T_D}} \newcommand{\TDA}{\den{T_{D_A}}} \newcommand{\TDB}{\den{T_{D_B}}} \newcommand{\TDP}{\den{T_{P_D}}} \newcommand{\TE}{\den{T_E}} \newcommand{\TLE}{\den{T_{L_E}}} \newcommand{\TLH}{\den{T_{L_H}}} %%% \newcommand{\TG}{\den{T_G}} \newcommand{\TQ}{\den{T_Q}} %%% \newcommand{\TR}{\den{T_R}} \newcommand{\TF}{\den{T_F}} \newcommand{\TFA}{\den{T_F'}} \newcommand{\TP}{\den{T_P}} \newcommand{\TPP}{\den{T_P'}} \newcommand{\TPS}{\den{T_{PS}}} \newcommand{\MGU}{\ti{MGU}} \newcommand{\TI}{\den{T_I}} \newcommand{\TL}{\den{T_L}} \newcommand{\TM}{\den{T_M}} %%% \newcommand{\TO}{\den{T_O}} \newcommand{\TS}{\den{T_S}} \newcommand{\TV}{\den{T_V}} \newcommand{\tenvm}{\ddot{\nabla}} \renewcommand{\tb}[1]{\triangleright#1\triangleleft} \newcommand{\unbindvar}[2]{\ti{unbindvar}\ \db{#1}\ #2} \newcommand{\unbindcon}[2]{\ti{unbindcon}\ \db{#1}\ #2} % Haskell syntax macros: math mode assumed \newcommand{\system}[2]{#1@;;@\cdots@;;@#2} \newcommand{\module}[4]{module\ #1@:@\ #2\ #3\ #4} \newcommand{\exposing}[1]{@expose@\ #1} \newcommand{\hiding}[1]{@hide@\ #1} \newcommand{\importnone}{\;} \newcommand{\importcomb}[2]{#1\ @;;@\ #2} \newcommand{\import}[2]{@import@\ #1\ #2} \newcommand{\rename}[2]{#1\ @=@\ #2} \newcommand{\declcomb}[2]{#1\ @;;@\ #2} \newcommand{\type}[2]{@type@\ #1\ @=@\;#2} \newcommand{\data}[2]{@data@\ #1\ @=@\;#2} \newcommand{\tuple}[2]{@tuple@\ #1\ @=@\;#2} %%% NEW! \newcommand{\view}[3]{@view@\ #1\ @=@\;#2\ @where@\ @{@\ #3\ @}@} \newcommand{\class}[2]{@class@\ #1\ @where@\ @{@\ #2\ @}@} \newcommand{\instance}[2]{@instance@\ #1\ @where@\ @{@\ #2\ @}@} \newcommand{\signature}[2]{#1\ @::@\ #2} \newcommand{\binding}[2]{#1\ @=@\ #2} \newcommand{\lamexpr}[2]{@\@ #1 @->@ #2} % While lambda defs. change... if change, take care of preceding line MMG \newcommand{\lamb}{@\ @} \newcommand{\whereexpr}[2]{#1\ @where@\ @{@\ #2\ @}@} \newcommand{\compexpr}[2]{@[@#1\ @|@\ #2@]@} \newcommand{\genclause}[2]{#1\ @<-@\ #2} \newcommand{\qualcomb}[2]{#1\ @,@\ #2} \newcommand{\genguard}[1]{\ #1\ } \newcommand{\caseexpr}[2]{@case@\ #1\ @of@\ @{@\ #2\ @}@} \newcommand{\simplecaseexpr}[5]{@case@\ #1\ @of@\ @{@\ #2\ @->@\ #3;\ #4\ @->@\ #5\ @}@} \newcommand{\iteexpr}[3]{@if@\ #1\ @then@\ #2\ @else@\ #3} \newcommand{\itexpr}[2]{@if@\ #1\ @then@\ #2} \newcommand{\gpat}[2]{#1\ @|@\ #2} \newcommand{\aspat}[2]{#1 @ @@ @ #2} \newcommand{\fclause}[2]{#1\ @=@\ #2} \newcommand{\fsym}[2]{#1\ @;@\ #2} \newcommand{\fpri}[2]{#1\ @;@\ @else@\ @;@\ #2} \newcommand{\aclause}[2]{#1\ @->@\ #2} \newcommand{\saclause}[4]{#1\ @->@\ #2;\ #3\ @->@\ #4} \newcommand{\asym}[2]{#1\ @;@\ #2} \newcommand{\apri}[2]{#1\ @;@\ @else@\ @;@\ #2} \newcommand{\dotted}[3]{#1\ #2\ \ldots\ #3} \newcommand{\functype}[2]{#1\ @->@\ #2} \newcommand{\predtype}[2]{#1\ @=>@ #2} \newcommand{\xp}{\dotted{x}{p_1}{p_n}} \newcommand{\xpg}{\dotted{x}{p_1}{p_n\ @{@\ g\ @}@}} \newcommand{\es}{e_1\ \ldots\ e_n} \newcommand{\ps}{p_1\ \ldots\ p_n} \newcommand{\vs}{v_1\ \ldots\ v_n} %%% NEW \newcommand{\xs}{x_1\ \ldots\ x_n} %%% NEW \newcommand{\cT}{\dotted{c}{T_1}{T_n}} \newcommand{\cTm}{\dotted{c_i}{T_{i1}}{T_{in_i}}\, @|@\range{i=1}{m}} % syntax meta-language \newcommand{\arity}[1]{\tr{arity}\ #1} \newcommand{\infix}[1]{\tr{infix}\ #1} \newcommand{\prefix}[1]{\tr{prefix}\ #1} % \newcommand{\tl}[1]{{\sc #1}} \newcommand{\Haskell}{Haskell} \newcommand{\subsubsubsection}{\subsubsection*} \newcommand{\subsubsubsubsection}{\subsubsubsection*} %\sloppy % a few hyphenation patterns, anyone? \hyphenation{da-ta-type da-ta-types} \hyphenation{Has-kell} \begin{document} \input{iso-chars} % Set the float fractions to sensible values \setcounter{topnumber}{2} \setcounter{bottomnumber}{0} \setcounter{totalnumber}{2} \setcounter{dbltopnumber}{2} \renewcommand{\textfraction}{0.1} \renewcommand{\floatpagefraction}{0.9} \renewcommand{\dblfloatpagefraction}{0.9} \setcounter{page}{0} % ------------------------- Title page ----------------------------------- \begin{titlepage} \setcounter{page}{0} \outline{ \vspace{.3in} \begin{center} {\LARGE\bf Haskell 98 Language and Libraries} \\[.1in] {\LARGE\bf The Revised Report} \\[.3in] \end{center} \vspace{.3in} } \vspace{.15in} \begin{center} \large Simon Peyton Jones (editor) \end{center} \vspace{.15in} \vspace{3in} \begin{center} \emph{Copyright notice.} \end{center} The authors and publisher intend this Report to belong to the entire Haskell community, and grant permission to copy and distribute it for 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 a definition of the language Haskell 98. \end{titlepage} % ------------------------- Preface ----------------------------------- \pagenumbering{roman} \clearpage \clearpage \tableofcontents \startnewstuff \parskip=10pt plus2pt minus2pt \setlength{\parindent}{0cm} \input{preface-jfp} % ------------------------- Part I: language report ----------------------------------- \pagestyle{headings} \startnewstuff \pagenumbering{arabic} \part{The Haskell 98 Language} \input{intro}\startnewsection \input{lexemes}\startnewsection \input{exps}\startnewsection \input{decls}\startnewsection \input{modules}\startnewsection \input{basic}\startnewsection \input{io-13}\startnewsection % \appendix \input{standard-prelude}\startnewsection \input{syntax-iso}\startnewsection \input{derived}\startnewsection \input{pragmas} %% % ------------------------- Part II: libraries report ----------------------------------- \part{The Haskell 98 Libraries} \label{libraries} \input{ratio}\startnewsection \input{complex}\startnewsection \input{numeric}\startnewsection \input{ix}\startnewsection \input{array}\startnewsection \input{list}\startnewsection \input{maybe}\startnewsection \input{char}\startnewsection \input{monad}\startnewsection \input{io}\startnewsection \input{directory}\startnewsection \input{system}\startnewsection \input{time}\startnewsection \input{locale}\startnewsection \input{cputime}\startnewsection \input{random}\startnewsection % ------------------------- Index and references ----------------------------------- \startnewstuff % insert the extra indexing things LAST \input{index-extra} % Add a contents line for the References -- may be off by one page \addcontentsline{toc}{section}{References} \bibliographystyle{plain} \bibliography{haskell} % \startnewstuff \printindex \end{document} % Local Variables: % mode: latex % End: haskell98-report-20080907/report/plain_haskell.verb0000644000175000017500000004334311345221573021451 0ustar marcotmarcot% % $Header: /home/cvs/root/haskell-report/report/plain_haskell.verb,v 1.4 2002/12/02 11:22:02 simonpj Exp $ % % NOTE:-------------------------------------------------------------- % The formatting of this report and the ``new font selection scheme'' % for LaTeX don't agree w/ each other. Using an ``oldlfont'' style % option may help. % ------------------------------------------------------------------- % % ------------------------------------------------------------------- % formatting for ONE-SIDED printing: % * De-comment the \documentstyle, etc., here; comment out the % two-sided ones below. % * Change the definition of \startnewstuff (below). % * Copy the pre-built index file for one-sided printing: % cp haskell.ind.one-sided haskell.ind % * Comment out the "twosidefix" stuff from Joe Fasel, just below. % * If you don't have "makeindex", make the adjustments % listed in the README file. % * Run "make haskell.dvi" several times (three, at most) to be % sure that cross-references stabilise. [For the 1.1 report, % one run should be enough.] %\documentstyle[11pt,makeidx]{article} %\oddsidemargin=.25in %\evensidemargin=.25in % formatting for double-sided \documentclass[titlepage,twoside,11pt]{article} \usepackage{makeidx} \usepackage{graphicx} \evensidemargin=0in \oddsidemargin=.5in % Inverted for SIGPLAN -- Page 1 is a LEFT page!! %\evensidemargin=.5in %\oddsidemargin=0in %--------------------------------------------------------------------- % Joe Fasel said this "twosidefix" is necessary if you really % have a two-sided printer: % (note: double @@'s for verbatim-ery) \makeatletter \def\titlepage{\@@restonecolfalse\if@@twocolumn\@@restonecoltrue\onecolumn \else \newpage \fi \thispagestyle{empty}\c@@page\m@@ne} \def\endtitlepage{\if@@twoside\newpage\thispagestyle{empty}\hbox{} \else \c@@page\@@z \fi \if@@restonecol\twocolumn \else \newpage \fi} \makeatother %--------------------------------------------------------------------- \sloppy % the major sections have \cleardoublepages between them % if you want those between EVERY section, change the % following defn: \newcommand{\startnewsection}{\clearpage} % % if doing one-sided printing, change this defn to % be just "\clearpage": \newcommand{\startnewstuff}{\cleardoublepage} % keep some pages from looking unbelievably appalling \raggedbottom % Fix those ugly floating figures. \renewcommand{\floatpagefraction}{0.1} \renewcommand{\textfraction}{0.1} \renewcommand{\topfraction}{1.0} \renewcommand{\bottomfraction}{1.0} % table of contents: show only down to subsections \setcounter{tocdepth}{2} % general formatting \textheight=8.5in \textwidth=6.0in \topmargin=0in \pagestyle{headings} \makeindex % an extra thing for makeindex \newcommand{\hseealso}[2]{{\em see also\/} #1} % NEWCOMMANDS % general \newcommand{\folks}[1]{\begin{quote}\sf#1\end{quote}} \newcommand{\sectionpart}[1]{\vspace{2 ex}\noindent{\bf #1}} \newcommand{\bq}{\begin{quote}} \newcommand{\eq}{\end{quote}} \newcommand{\bt}{\begin{tabular}} \newcommand{\et}{\end{tabular}} \newcommand{\bto}{\begin{tabular}} \newcommand{\eto}{\end{tabular}} \newcommand{\bi}{\begin{itemize}} \newcommand{\ei}{\end{itemize}} \newcommand{\struthack}[1]{\rule{0pt}{#1}} \newcommand{\inputHS}{\input} \newcommand{\ToDo}[1]{} %\newcommand{\ToDo}[1]{({\bf $\spadesuit$ ToDo:} {\em #1})} \newcommand{\WeSay}[1]{} %\newcommand{\WeSay}[1]{({\bf $\clubsuit$ YaleSays:} {\em #1})} \newcommand{\anchor}[2]{#2} % indexing \newcommand{\indextt}[1]{\index{#1@@{\tt #1}}} \newcommand{\indexsyn}[1]{\index{#1@@{\it #1}}} \newcommand{\indexmodule}[1]{\index{#1@@{\tt #1} (module)}} \newcommand{\indextycon}[1]{\index{#1@@{\tt #1} (datatype)}} \newcommand{\indexsynonym}[1]{\index{#1@@{\tt #1} (type synonym)}} \newcommand{\indexclass}[1]{\index{#1@@{\tt #1} (class)}} \newcommand{\indexdi}[1]{\index{#1@@{\tt #1} (class)!derived instance}} \newcommand{\indexnote}[1]{#1n} \newcommand{\emptystr}{[\,]} \makeatletter \def\theindex{\@@restonecoltrue\if@@twocolumn\@@restonecolfalse\fi \columnseprule \z@@ \columnsep 35pt\twocolumn[\section*{Index} \addcontentsline{toc}{section}{Index} \input{index-intro}\vskip 20pt] \@@mkboth{INDEX}{INDEX}\thispagestyle{plain}\parindent\z@@ \parskip\z@@ plus .3pt\relax\let\item\@@idxitem } \makeatother % outlined figures \newcommand{\ecaption}[1]{\vspace{-1 ex}\caption{#1}\vspace{1 ex}} % partain fiddled here... % also had to change two lines in verbatim.lex from %{nl}"|"{sp} { printf ("$\\\\ \n$\\it "); % printf ("$\\>\\makebox[3em]{$|$}$\\it "); } % to % %{nl}"|"{sp} { printf ("$\\\\ \n$\\it "); % printf ("$\\>\\makebox[3.5em]{$|$}$\\it "); } % so things would still line up. Oh what a hack. % %\newcommand{\outline}{\outlinewidth{1.0}} %\newcommand{\outlinewidth}[2]{ %\begin{center} %\fbox{ \begin{minipage}{#1\textwidth} %\vspace{1 ex} %#2 %\end{minipage} } %\vspace{1 ex} %\end{center} %} % 6.0in (\textwidth) - 15pt (overfullness) ~=~ 415pt \newcommand{\outline}[1]{% \begin{center} \fbox{ \begin{minipage}{415pt} \vspace{1 ex} #1 \end{minipage} } \vspace{1 ex} \end{center} } \newcommand{\outlinec}{\outline} % Centered outlines in html % haskell code % partain fiddled here... % \newcommand{\bprog}{\par \begin{tabular}{|l} % \mbox \bgroup \begin{minipage} {\textwidth} } % 6.0in (\textwidth) - 17pt (\parindent) ~=~ 412pt %\newcommand{\bprog}{\par \begin{tabular}{@@{}l@@{}} % \mbox \bgroup \begin{minipage} {412pt} } %\newcommand{\eprog}{\end{minipage} % \egroup % \end{tabular}\\[\parskip]} % 17pt is \parindent % this method gives a 17pt indent in _all_ situations \newcommand{\bprog}{% \par\noindent\begin{tabular}{@@{\hspace*{17pt}}l@@{}}} \newcommand{\eprog}{% \end{tabular}\\[\parskip]} \newcommand{\eprogNoSkip}{% \end{tabular}} % % variants for stdprelude; don't indent, and skip a little more \newcommand{\bprogB}{% \begin{tabular}{@@{}l@@{}}} \newcommand{\eprogB}{% \end{tabular}\\[0.6\baselineskip]} %special characters \newcommand{\bkq}{\mbox{\it \char'022}} % (syntax) backquote char \newcommand{\bkqB}{\bkq} % (syntax) backquote char (Before) \newcommand{\bkqA}{\hspace{-.2em}\mbox{\it \char'022}}% (syntax) backquote char (After) %\newcommand{\fwq}{\mbox{\it \char'023}} % (syntax) (forward) quote char % math formatting \newcommand{\ba}{\begin{array}} \newcommand{\ea}{\end{array}} \newcommand{\mc}{\multicolumn} \newcommand{\pile}[1]{\ba[t]{@@{}l@@{}} #1 \ea} \newcommand{\eqn}[1]{\ba[t]{@@{}lcl@@{}} #1 \ea} \newcommand{\equate}[1]{\[\eqn{#1}\]} \newcommand{\la}{\leftarrow} \newcommand{\ra}{\rightarrow} \newcommand{\sq}[1]{[\,#1\,]} \newcommand{\ab}[1]{\langle#1\rangle} \newcommand{\ablarge}[1]{\langle \pile{#1\,\rangle}} \newcommand{\lb}{[\![} \newcommand{\rb}{]\!]} \newcommand{\db}[1]{\lb#1\rb} \newcommand{\ti}[1]{\mbox{{\it #1}}} \newcommand{\tr}[1]{\mbox{{\rm #1}}} \newcommand{\tb}[1]{\mbox{{\bf #1}}} \newcommand{\x}{\times} \newcommand{\lam}{\lambda} \newcommand{\kr}{\kappa_{\rho}} \newcommand{\syneq}{\rightarrow} % denotational semantics \newcommand{\denote}[3]{\[\ba{c} {\cal #1} : #2 \\[1 ex] #3 \ea\]} \newcommand{\den}[2]{{\cal #1}\db{#2}\,} \newcommand{\A}{\den{A}} \newcommand{\B}{\den{B}} \newcommand{\D}{\den{D}} \newcommand{\E}{\den{E}} \newcommand{\F}{\den{F}} \newcommand{\G}{\den{G}} \newcommand{\I}{\den{I}} %%% \renewcommand{\L}{\den{L}} \newcommand{\LE}{\den{L_E}} \newcommand{\LH}{\den{L_H}} \newcommand{\M}{\den{M}} %%% \renewcommand{\O}{\den{O}} \renewcommand{\P}{\den{P}} \newcommand{\Pbot}{\den{P_{\bot}}} \newcommand{\Q}{\den{Q}} \newcommand{\R}{\den{R}} \renewcommand{\S}{\den{S}} \newcommand{\V}{\den{V}} \newcommand{\W}{\den{W}} \newcommand{\T}[2]{\den{T}{#1}\,\db{#2}} % meta language \newcommand{\PP}{\den{P'}} \newcommand{\PS}{\den{P_S}} \newcommand{\otherwise}{\quad\tr{otherwise}} \newcommand{\case}[2]{\pile{ \tr{case}\ (#1)\ \tr{of} \\ \ba{@@{\quad}l@@{\ \ra\ }l@@{}} #2 \ea}} \newcommand{\where}[2]{#1 \quad\tr{where}\quad #2} \newcommand{\wherelarge}[2]{\pile{#1 \\ \tr{where} \\ \eqn{#2}}} \newcommand{\cond}[3]{#1 \ra #2,\ #3} \newcommand{\condlarge}[1]{\ba[t]{@@{}l@@{\ \ra\ }l@@{}} #1 \ea} \newcommand{\range}[2]{{}_{#1}^{#2}\,} % semantic operators \newcommand{\concat}{\frown} \newcommand{\seq}[1]{\ti{List}\ #1} \newcommand{\opt}[1]{\widetilde{#1}} \newcommand{\ov}{\opt{v}} \newcommand{\fail}{\ti{none}} \newcommand{\nonfail}{\ti{proper}} \newcommand{\sym}{\bigtriangledown} \newcommand{\pri}{\mathbin{\vec{\sym}}} \newcommand{\mrg}{\mathbin{\dot{\sym}}} \newcommand{\Sym}{\mathbin{\nabla}} \newcommand{\Pri}{\mathbin{\vec{\Sym}}} \newcommand{\Mrg}{\mathbin{\dot{\Sym}}} \newcommand{\optSym}{\mathbin{\opt{\Sym}}} \newcommand{\optodot}{\mathbin{\opt{\odot}}} \newcommand{\proj}{\mid} \newcommand{\restrict}{\setminus} \newcommand{\sel}[4]{\ti{sel}_{#3#2}\ #4} \newcommand{\bindnone}{\ti{bindnone}} \newcommand{\bindvar}[2]{\ti{bindvar}\ \db{#1}\ #2} \newcommand{\bindcon}[2]{\ti{bindcon}\ \db{#1}\ #2} \newcommand{\bindconlarge}[4]{ #4\ \bindcon{#1}{\ablarge{ #2, \\ #3}}} \newcommand{\bindmod}[2]{\ti{bindmod}\ \db{#1}\ #2} \newcommand{\lookupval}[2]{\ti{lookupval}\ #1\ \db{#2}} %%% NEW \newcommand{\lookupcon}[1]{\ti{lookupcon}\ \db{#1}} %%% NEW \newcommand{\lookupdecon}[2]{\ti{lookupdecon}\ #1\ \db{#2}} %%% NEW % used in static.verb \newcommand{\TT}{\den{T_T}} \newcommand{\TA}{\den{T_A}} \newcommand{\TB}{\den{T_B}} \newcommand{\TD}{\den{T_D}} \newcommand{\TDA}{\den{T_{D_A}}} \newcommand{\TDB}{\den{T_{D_B}}} \newcommand{\TDP}{\den{T_{P_D}}} \newcommand{\TE}{\den{T_E}} \newcommand{\TLE}{\den{T_{L_E}}} \newcommand{\TLH}{\den{T_{L_H}}} %%% \newcommand{\TG}{\den{T_G}} \newcommand{\TQ}{\den{T_Q}} %%% \newcommand{\TR}{\den{T_R}} \newcommand{\TF}{\den{T_F}} \newcommand{\TFA}{\den{T_F'}} \newcommand{\TP}{\den{T_P}} \newcommand{\TPP}{\den{T_P'}} \newcommand{\TPS}{\den{T_{PS}}} \newcommand{\MGU}{\ti{MGU}} \newcommand{\TI}{\den{T_I}} \newcommand{\TL}{\den{T_L}} \newcommand{\TM}{\den{T_M}} %%% \newcommand{\TO}{\den{T_O}} \newcommand{\TS}{\den{T_S}} \newcommand{\TV}{\den{T_V}} \newcommand{\tenvm}{\ddot{\nabla}} \renewcommand{\tb}[1]{\triangleright#1\triangleleft} \newcommand{\unbindvar}[2]{\ti{unbindvar}\ \db{#1}\ #2} \newcommand{\unbindcon}[2]{\ti{unbindcon}\ \db{#1}\ #2} % % \newcommand{\bindnone}{\ab{[], []}} % \newcommand{\bindvar}[2]{\ab{[\,#1 \mapsto #2\,], []}} % \newcommand{\bindcon}[2]{\ab{[], [\,#1 \mapsto #2\,]}} % \newcommand{\bindconlarge}[4]{ % \langle [], [\,#1 \mapsto \langle \pile{#2 \\ #3 \rangle\,] #4 \rangle}} % \newcommand{\bindmod}[2]{[\,#1 \mapsto #2\,]} % % Haskell syntax macros: math mode assumed \newcommand{\system}[2]{#1@;;@\cdots@;;@#2} \newcommand{\module}[4]{module\ #1@:@\ #2\ #3\ #4} %%% \newcommand{\exportnone}{\,} %%% \newcommand{\export}[1]{@export@\ #1@;@} %%% \newcommand{\importnone}{\,} %%% \newcommand{\importcomb}[2]{#1\ #2} %%% \newcommand{\import}[1]{@import@\ #1@;@} %%% \newcommand{\importwith}[2]{@import@\ #1\ #2@;@} %%% \newcommand{\rename}[2]{#1@<-@#2} %%% \newcommand{\declcomb}[2]{#1\ @;;@\ #2} \newcommand{\exposing}[1]{@expose@\ #1} \newcommand{\hiding}[1]{@hide@\ #1} \newcommand{\importnone}{\;} \newcommand{\importcomb}[2]{#1\ @;;@\ #2} \newcommand{\import}[2]{@import@\ #1\ #2} \newcommand{\rename}[2]{#1\ @=@\ #2} \newcommand{\declcomb}[2]{#1\ @;;@\ #2} \newcommand{\type}[2]{@type@\ #1\ @=@\;#2} \newcommand{\data}[2]{@data@\ #1\ @=@\;#2} \newcommand{\tuple}[2]{@tuple@\ #1\ @=@\;#2} %%% NEW! \newcommand{\view}[3]{@view@\ #1\ @=@\;#2\ @where@\ @{@\ #3\ @}@} \newcommand{\class}[2]{@class@\ #1\ @where@\ @{@\ #2\ @}@} \newcommand{\instance}[2]{@instance@\ #1\ @where@\ @{@\ #2\ @}@} \newcommand{\signature}[2]{#1\ @::@\ #2} \newcommand{\binding}[2]{#1\ @=@\ #2} \newcommand{\lamexpr}[2]{@\@ #1 @->@ #2} % While lambda defs. change... if change, take care of preceding line MMG \newcommand{\lamb}{@\ @} \newcommand{\whereexpr}[2]{#1\ @where@\ @{@\ #2\ @}@} \newcommand{\compexpr}[2]{@[@#1\ @|@\ #2@]@} \newcommand{\genclause}[2]{#1\ @<-@\ #2} \newcommand{\qualcomb}[2]{#1\ @,@\ #2} \newcommand{\genguard}[1]{\ #1\ } \newcommand{\caseexpr}[2]{@case@\ #1\ @of@\ @{@\ #2\ @}@} \newcommand{\simplecaseexpr}[5]{@case@\ #1\ @of@\ @{@\ #2\ @->@\ #3;\ #4\ @->@\ #5\ @}@} \newcommand{\iteexpr}[3]{@if@\ #1\ @then@\ #2\ @else@\ #3} \newcommand{\itexpr}[2]{@if@\ #1\ @then@\ #2} \newcommand{\gpat}[2]{#1\ @|@\ #2} \newcommand{\aspat}[2]{#1 @ @@ @ #2} \newcommand{\fclause}[2]{#1\ @=@\ #2} \newcommand{\fsym}[2]{#1\ @;@\ #2} \newcommand{\fpri}[2]{#1\ @;@\ @else@\ @;@\ #2} \newcommand{\aclause}[2]{#1\ @->@\ #2} \newcommand{\saclause}[4]{#1\ @->@\ #2;\ #3\ @->@\ #4} \newcommand{\asym}[2]{#1\ @;@\ #2} \newcommand{\apri}[2]{#1\ @;@\ @else@\ @;@\ #2} \newcommand{\dotted}[3]{#1\ #2\ \ldots\ #3} \newcommand{\functype}[2]{#1\ @->@\ #2} \newcommand{\predtype}[2]{#1\ @=>@ #2} \newcommand{\xp}{\dotted{x}{p_1}{p_n}} \newcommand{\xpg}{\dotted{x}{p_1}{p_n\ @{@\ g\ @}@}} \newcommand{\es}{e_1\ \ldots\ e_n} \newcommand{\ps}{p_1\ \ldots\ p_n} \newcommand{\vs}{v_1\ \ldots\ v_n} %%% NEW \newcommand{\xs}{x_1\ \ldots\ x_n} %%% NEW \newcommand{\cT}{\dotted{c}{T_1}{T_n}} \newcommand{\cTm}{\dotted{c_i}{T_{i1}}{T_{in_i}}\, @|@\range{i=1}{m}} % syntax meta-language \newcommand{\arity}[1]{\tr{arity}\ #1} \newcommand{\infix}[1]{\tr{infix}\ #1} \newcommand{\prefix}[1]{\tr{prefix}\ #1} % \newcommand{\tl}[1]{{\sc #1}} %OLD: \newcommand{\Haskell}{{\sc Haskell}} \newcommand{\Haskell}{Haskell} %\newcommand{\subsubsubsection}[1]{\par\noindent{\it #1}} \newcommand{\subsubsubsection}{\subsubsection*} %\sloppy % a few hyphenation patterns, anyone? \hyphenation{da-ta-type da-ta-types} \hyphenation{Has-kell} \begin{document} \input{iso-chars} % Set the float fractions to sensible values \setcounter{topnumber}{2} \setcounter{bottomnumber}{0} \setcounter{totalnumber}{2} \setcounter{dbltopnumber}{2} \renewcommand{\textfraction}{0.1} \renewcommand{\floatpagefraction}{0.9} \renewcommand{\dblfloatpagefraction}{0.9} \setcounter{page}{0} \begin{titlepage} \setcounter{page}{0} \outline{ \vspace{.3in} \begin{center} {\LARGE\bf Report on the} \\[.1in] {\LARGE\bf Programming Language} \\[.3in] {\huge\bf Haskell 98} \\[.3in] {\Large\bf A Non-strict, Purely Functional Language} \\[.3in] {\large\bf Revised: FILL IN DATE!!} \end{center} \vspace{.15in} \begin{center} \large \begin{tabular}{l@@{\hspace{5mm}}l} Simon Peyton Jones$^8$ [editor] & John Hughes$^3$ [editor] \\ Lennart Augustsson$^3$ & Dave Barton$^7$ \\ Brian Boutel$^4$ & Warren Burton$^5$ \\ Joseph Fasel$^6$ & Kevin Hammond$^2$ \\ Ralf Hinze$^{12}$ & Paul Hudak$^1$ \\ Thomas Johnsson$^3$ & Mark Jones$^9$ \\ John Launchbury$^{14}$ & Erik Meijer$^{10}$ \\ John Peterson$^1$ & Alastair Reid$^1$ \\ Colin Runciman$^{13}$ & Philip Wadler$^{11}$ \end{tabular} \end{center} \vspace{.15in} \begin{quotation} \noindent Authors' affiliations: (1)~Yale University (2)~University of St.~Andrews (3)~Chalmers University of Technology (4)~Victoria University of Wellington (5)~Simon Fraser University (6)~Los Alamos National Laboratory (7)~Intermetrics (8)~Microsoft Research, Cambridge (9)~University of Nottingham (10)~Utrecht University (11)~Bell Labs (12)~University of Bonn (13)~York University (14)~Oregon Graduate Institute \end{quotation} \vspace{.2in} \begin{center} Copyright (c) Simon Peyton Jones and John Hughes. \end{center} {\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 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 a definition of the language Haskell 98.} } % \outline{ % \vspace{.3in} % \begin{center} % {\LARGE\bf Report on the} \\[.1in] % {\LARGE\bf Programming Language} \\[.3in] % {\huge\bf Haskell} \\[.3in] % {\Large\bf A Non-strict, Purely Functional Language} \\[.3in] % {\Large\bf Version 1.3} \\[.1in] % {\large\bf 1st June 1995} % \end{center} % \vspace{.15in} % \begin{center} \large % Kevin Hammond$^1$ [editor] \\ % Lennart Augustsson$^2$ \\ % Brian Boutel$^3$ \\ % Warren Burton$^4$ \\ % Joseph Fasel$^5$ \\ % Andy Gordon$^6$ \\ % Mark Jones$^7$ \\ % John Peterson$^8$ \\ % Simon Peyton Jones$^1$ \\ % \end{center} % \vspace{.15in} % % \begin{quotation} \noindent % Authors' affiliations: % (1)~University of Glasgow, % (2)~Chalmers University of Technology, % (3)~Victoria University of Wellington, % (4)~Simon Fraser University, % (5)~Los Alamos National Laboratory, % (6)~Cambridge University, % (7)~Nottingham University, % (8)~Yale University. % \end{quotation} % \vspace{.2in} % } \end{titlepage} \pagenumbering{roman} \clearpage \clearpage \tableofcontents \startnewstuff \parskip=10pt plus2pt minus2pt \setlength{\parindent}{0cm} %\input{preface-10} %\startnewstuff %\input{preface-11} %\startnewstuff %\input{preface-12} %\startnewstuff %\pagestyle{myheadings} \input{preface-13} %\markboth{\rm \thepage\hfil \sl \leftmark}{{\sl \rightmark}\hfil \rm\thepage} \pagestyle{headings} \startnewstuff \pagenumbering{arabic} \input{intro}\startnewsection \input{lexemes}\startnewsection \input{exps}\startnewsection \input{decls}\startnewsection \input{modules}\startnewsection \input{basic}\startnewsection %%\input{io}% %\setcounter{section}{6} \input{io-13}% %% %%\startnewstuff \startnewsection \appendix \input{standard-prelude}\startnewsection %\input{libraries}\startnewsection \input{syntax-iso}\startnewsection \input{literate}\startnewsection %% \input{short_semantics}\startnewsection %%\input{iosemant}\startnewsection %%\input{iooptions}\startnewsection \input{derived}\startnewsection \input{pragmas} %% \startnewstuff % insert the extra indexing things LAST \input{index-extra} % Add a contents line for the References -- may be off by one page \addcontentsline{toc}{section}{References} \bibliographystyle{plain} \bibliography{haskell} % \startnewstuff \printindex \end{document} % Local Variables: % mode: latex % End: haskell98-report-20080907/report/ix.verb0000644000175000017500000000743111345221573017261 0ustar marcotmarcot%**The Haskell 98 Library Report: Indexing Operations %**~header \section{Indexing Operations} \outline{ \inputHS{lib-hdrs/Ix} } The @Ix@ class is used to map a contiguous subrange of values in a type onto integers. It is used primarily for array indexing (see Chapter~\ref{arrays}). The @Ix@ class contains the methods @range@\indextt{range}, @index@\indextt{index}, and @inRange@\indextt{inRange}. The @index@ operation maps a bounding pair, which defines the lower and upper bounds of the range, and a subscript, to an integer. The @range@ operation enumerates all subscripts; the @inRange@ operation tells whether a particular subscript lies in the range defined by a bounding pair. An implementation is entitled to assume the following laws about these operations: \bprog @ range (l,u) !! index (l,u) i == i -- when i is in range inRange (l,u) i == i `elem` range (l,u) map index (range (l,u)) == [0..rangeSize (l,u)] @ \eprog % It is the responsibility of the programmer to enforce bounds % checking for non-derived instances of class @Ix@, if desired. % An implementation is not required to check that an index % lies within the bounds of an array when accessing that array. \subsection{Deriving Instances of @Ix@} \indexdi{Ix} It is possible to derive an instance of @Ix@ automatically, using a @deriving@ clause on a @data@ declaration (Section~\ref{derived-decls}). Such derived instance declarations for the class @Ix@ are only possible for enumerations\index{enumeration} (i.e.~datatypes having only nullary constructors) and single-constructor datatypes, whose constituent types are instances of @Ix@. A Haskell implementation must provide @Ix@ instances for tuples up to at least size 15. \begin{itemize} \item For an {\em enumeration}, the nullary constructors are assumed to be numbered left-to-right with the indices being $0$ to $n-1\/$ inclusive. This is the same numbering defined by the @Enum@ class. For example, given the datatype: \bprog @ data Colour = Red | Orange | Yellow | Green | Blue | Indigo | Violet @ \eprog we would have: \bprog @ range (Yellow,Blue) == [Yellow,Green,Blue] index (Yellow,Blue) Green == 1 inRange (Yellow,Blue) Red == False @ \eprog \item For {\em single-constructor datatypes}, the derived instance declarations are as shown for tuples in Figure~\ref{prelude-index}. \end{itemize} \begin{figure}[tb] \outline{\small @ instance (Ix a, Ix b) => Ix (a,b) where range ((l,l'),(u,u')) = [(i,i') | i <- range (l,u), i' <- range (l',u')] index ((l,l'),(u,u')) (i,i') = index (l,u) i * rangeSize (l',u') + index (l',u') i' inRange ((l,l'),(u,u')) (i,i') = inRange (l,u) i && inRange (l',u') i' -- Instances for other tuples are obtained from this scheme: -- -- instance (Ix a1, Ix a2, ... , Ix ak) => Ix (a1,a2,...,ak) where -- range ((l1,l2,...,lk),(u1,u2,...,uk)) = -- [(i1,i2,...,ik) | i1 <- range (l1,u1), -- i2 <- range (l2,u2), -- ... -- ik <- range (lk,uk)] -- -- index ((l1,l2,...,lk),(u1,u2,...,uk)) (i1,i2,...,ik) = -- index (lk,uk) ik + rangeSize (lk,uk) * ( -- index (lk-1,uk-1) ik-1 + rangeSize (lk-1,uk-1) * ( -- ... -- index (l1,u1))) -- -- inRange ((l1,l2,...lk),(u1,u2,...,uk)) (i1,i2,...,ik) = -- inRange (l1,u1) i1 && inRange (l2,u2) i2 && -- ... && inRange (lk,uk) ik @ } \ecaption{Derivation of Ix instances} \label{prelude-index} \indexclass{Ix} \indextt{range}\indextt{index}\indextt{inRange} \indextt{rangeSize} \end{figure} \clearpage \subsection{Library {\tt Ix}} \inputHS{lib-code/Ix} %**~footer haskell98-report-20080907/report/syntax-lexical.verb0000644000175000017500000000525411345221573021607 0ustar marcotmarcot% % $Header: /home/cvs/root/haskell-report/report/syntax-lexical.verb,v 1.10 2003/01/13 13:08:56 simonpj Exp $ % @@@ program -> \{ lexeme | whitespace \} lexeme -> qvarid | qconid | qvarsym | qconsym | literal | special | reservedop | reservedid literal -> integer | float | char | string special -> @(@ | @)@ | @,@ | @;@ | @[@ | @]@ | \bkq | @{@ | @}@ whitespace -> whitestuff \{whitestuff\} whitestuff -> whitechar | comment | ncomment whitechar -> newline | vertab | space | tab | uniWhite newline -> return linefeed | return | linefeed | formfeed return -> \tr{a carriage return} linefeed -> \tr{a line feed} vertab -> \tr{a vertical tab} formfeed -> \tr{a form feed} space -> \tr{a space} tab -> \tr{a horizontal tab} uniWhite -> \tr{any Unicode character defined as whitespace} comment -> dashes [ any_{\langle{}symbol\rangle} \{any\} ] newline dashes -> @--@ \{@-@\} opencom -> @{-@ closecom -> @-}@ ncomment -> opencom ANYseq \{ncomment ANYseq\} closecom ANYseq -> \{ANY\}_{\langle{}\{ANY\} ( opencom | closecom ) \{ANY\}\rangle{}} ANY -> graphic | whitechar any -> graphic | space | tab graphic -> small | large | symbol | digit | special | @:@ | @"@ | @'@ small -> ascSmall | uniSmall | @_@ ascSmall -> @a@ | @b@ | ... | @z@ uniSmall -> \tr{any Unicode lowercase letter} large -> ascLarge | uniLarge ascLarge -> @A@ | @B@ | ... | @Z@ uniLarge -> \tr{any uppercase or titlecase Unicode letter} symbol -> ascSymbol | uniSymbol_{\langle{}special | @_@ | @:@ | @"@ | @'@\rangle{}} ascSymbol -> @!@ | @#@ | @$@ | @%@ | @&@ | @*@ | @+@ | @.@ | @/@ | @<@ | @=@ | @>@ | @?@ | @@ | @\@ | @^@ | @|@ | @-@ | @~@ uniSymbol -> \tr{any Unicode symbol or punctuation} digit -> ascDigit | uniDigit ascDigit -> @0@ | @1@ | ... | @9@ uniDigit -> \tr{any Unicode decimal digit} octit -> @0@ | @1@ | ... | @7@ hexit -> digit | @A@ | ... | @F@ | @a@ | ... | @f@ @@@ \indexsyn{program}% \indexsyn{lexeme}% \indexsyn{literal}% \indexsyn{special}% \indexsyn{whitespace}% \indexsyn{whitestuff}% \indexsyn{whitechar}% \indexsyn{uniWhite}% \indexsyn{newline}% \indexsyn{space}% \indexsyn{tab}% \indexsyn{vertab}% \indexsyn{formfeed}% \indexsyn{comment}% \indexsyn{dashes}% \indexsyn{ncomment}% \indexsyn{opencom}% \indexsyn{closecom}% \indexsyn{ANYseq}% \indexsyn{ANY}% \indexsyn{any}% \indexsyn{graphic}% \indexsyn{small}% \indexsyn{ascSmall}% \indexsyn{uniSmall}% \indexsyn{uniDigit}% \indexsyn{large}% \indexsyn{ascLarge}% \indexsyn{uniLarge}% \indexsyn{symbol}% \indexsyn{ascSymbol}% \indexsyn{uniSymbol}% \indexsyn{digit}% \indexsyn{ascDigit}% \indexsyn{uniDigit}% \indexsyn{octit}% \indexsyn{hexit}% haskell98-report-20080907/report/intro.verb0000644000175000017500000002031711345221573017772 0ustar marcotmarcot% % $Header: /home/cvs/root/haskell-report/report/intro.verb,v 1.7 2002/12/10 11:51:11 simonpj Exp $ % %**The Haskell 98 Report: Introduction %*section 1 %**~header \section{Introduction} \label{introduction} \Haskell{}\index{Haskell@@\Haskell{}} is a general purpose, purely functional programming language incorporating many recent innovations in programming language design. \Haskell{} provides higher-order functions, non-strict semantics, static polymorphic typing, user-defined algebraic datatypes, pattern-matching, list comprehensions, a module system, a monadic I/O system, and a rich set of primitive datatypes, including lists, arrays, arbitrary and fixed precision integers, and floating-point numbers. \Haskell{} is both the culmination and solidification of many years of research on non-strict functional languages. % Although the initial emphasis was on standardization, \Haskell{} % also has several new features that both simplify and % generalize the design. For example, % \begin{enumerate} % \item Rather than using {\em ad hoc} techniques for % overloading,\index{overloading} % \Haskell{} provides an explicit overloading facility, integrated with % the polymorphic type system\index{type system}, that allows the % precise definition of overloading behavior for any operator or function. % \item The conventional notion of ``abstract data % type''\index{abstract datatype} % has been unbundled % into two orthogonal components: % data abstraction\index{data abstraction} % and information hiding.\index{information hiding} % \item \Haskell{} has a flexible I/O facility based on the use of % monads~\cite{Imperative-Functional-Programming}. The system supports % most of the standard operations provided by conventional operating % systems while retaining referential transparency within a program. % \item Recognising the importance of arrays, \Haskell{} has a % family of multidimensional non-strict immutable arrays\index{array} % whose special interaction with list comprehensions provides a % convenient ``array comprehension'' syntax for defining arrays % monolithically. % \end{enumerate} This report defines the syntax for \Haskell{} programs and an informal abstract semantics for the meaning of such programs. %; the formal abstract semantics is in preparation.% \index{formal semantics} We leave as implementation dependent the ways in which \Haskell{} programs are to be manipulated, interpreted, compiled, etc. This includes such issues as the nature of programming environments and the error messages returned for undefined programs (i.e.~programs that formally evaluate to $\bot$). \subsection{Program Structure}\index{program structure} \label{programs} In this section, we describe the abstract syntactic and semantic structure of \Haskell{}, as well as how it relates to the organization of the rest of the report. \begin{enumerate} \item At the topmost level a \Haskell{} program is a set of {\em modules}, described in Chapter~\ref{modules}. Modules provide a way to control namespaces and to re-use software in large programs. \item The top level of a module consists of a collection of {\em declarations}, of which there are several kinds, all described in Chapter~\ref{declarations}. Declarations define things such as ordinary values, datatypes, type classes, and fixity information. \item At the next lower level are {\em expressions}, described in Chapter~\ref{expressions}. An expression denotes a {\em value} and has a {\em static type}; expressions are at the heart of \Haskell{} programming ``in the small.'' \item At the bottom level is \Haskell{}'s {\em lexical structure}, defined in Chapter~\ref{lexical-structure}. The lexical structure captures the concrete representation of \Haskell{} programs in text files. \end{enumerate} This report proceeds bottom-up with respect to \Haskell{}'s syntactic structure. The chapters not mentioned above are Chapter~\ref{basic-types-and-classes}, which describes the standard built-in datatypes and classes in \Haskell{}, and Chapter~\ref{io}, which discusses the I/O facility in \Haskell{} (i.e.~how \Haskell{} programs communicate with the outside world). Also, there are several chapters describing the Prelude, the concrete syntax, literate programming, the specification of derived instances, and pragmas supported by most \Haskell{} compilers. Examples of \Haskell{} program fragments in running text are given in typewriter font: % highlighted with a vertical line to the left of the text: % as in: \bprog @ let x = 1 z = x+y in z+1 @ \eprog ``Holes'' in program fragments representing arbitrary pieces of \Haskell{} code are written in italics, as in "@if@ e_1 @then@ e_2 @else@ e_3". Generally the italicized names are mnemonic, such as "e" for expressions, "d" for declarations, "t" for types, etc. \subsection{The \Haskell{} Kernel} \index{Haskell kernel@@\Haskell{} kernel} \label{intro-kernel} \Haskell{} has adopted many of the convenient syntactic structures that have become popular in functional programming. In this Report, the meaning of such syntactic sugar is given by translation into simpler constructs. If these translations are applied exhaustively, the result is a program written in a small subset of Haskell that we call the \Haskell{} {\em kernel}. Although the kernel is not formally specified, it is essentially a slightly sugared variant of the lambda calculus with a straightforward denotational semantics. The translation of each syntactic structure into the kernel is given as the syntax is introduced. This modular design facilitates reasoning about \Haskell{} programs and provides useful guidelines for implementors of the language. % In specifying the translation of special syntax, named entities are % often referred to ``as defined in the standard prelude.'' This means % that even if these names are rebound (i.e.~the standard prelude name % is not currently in scope), the translation still takes on the meaning % as defined in the standard prelude. In other words, the meaning of % \Haskell{}'s syntax is invariant. \subsection{Values and Types} \index{value}\index{type} \label{errors}\index{error} An expression\index{expression} evaluates to a {\em value} and has a static {\em type}. Values and types are not mixed in \Haskell{}. However, the type system allows user-defined datatypes of various sorts, and permits not only parametric polymorphism\index{polymorphism} (using a traditional Hindley-Milner\index{Hindley-Milner type system} type structure) but also {\em ad hoc} polymorphism, or {\em overloading} (using {\em type classes}).\index{type class} Errors in \Haskell{} are semantically equivalent to $\bot$. Technically, they are not distinguishable from nontermination, so the language includes no mechanism for detecting or acting upon errors. However, implementations will probably try to provide useful information about errors. See Section~\ref{basic-errors}. \subsection{Namespaces} \index{namespaces} \label{namespaces} There are six kinds of names in \Haskell{}: those for {\em variables} and {\em constructors} denote values; those for {\em type variables}, {\em type constructors}, and {\em type classes} refer to entities related to the type system; and {\em module names} refer to modules. There are two constraints on naming:\nopagebreak[4] \begin{enumerate} \item Names for variables and type variables are identifiers beginning with lowercase letters or underscore; the other four kinds of names are identifiers beginning with uppercase letters. \item An identifier must not be used as the name of a type constructor and a class in the same scope. \end{enumerate} These are the only constraints; for example, @Int@ may simultaneously be the name of a module, class, and constructor within a single scope. %\subsection{Conformance} %A strictly-conforming \Haskell{} implementation implements this %language definition completely and exactly. A mostly-conforming %\Haskell{} implementation implements a large subset of this %definition, and provides full and complete documentation of any %extensions to or deviations from the specification given here. For %any conforming implementation, all implementation dependencies which %are allowed by the standard must be explicitly documented. %**~footer % Local Variables: % mode: latex % End: haskell98-report-20080907/report/array.verb0000644000175000017500000001544011345221573017756 0ustar marcotmarcot%**The Haskell 98 Library Report: Arrays %**~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] \outline{\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 @ } \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] \outline{\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) @ } \ecaption{Derived array examples} \label{derived-array-examples} \end{figure} \subsection{Library {\tt Array}} \label {Libarray} \inputHS{lib-code/Array} %**~footer haskell98-report-20080907/report/haskell.idx0000644000175000017500000024745011345221573020121 0ustar marcotmarcot\indexentry{functional language}{vii} \indexentry{Haskell@\Haskell{}}{vii} \indexentry{Curry, Haskell B.}{vii} \indexentry{Haskell@\Haskell{}}{3} \indexentry{formal semantics}{3} \indexentry{program structure}{3} \indexentry{Haskell kernel@\Haskell{} kernel}{4} \indexentry{value}{4} \indexentry{type}{4} \indexentry{error}{4} \indexentry{expression}{4} \indexentry{polymorphism}{4} \indexentry{Hindley-Milner type system}{4} \indexentry{type class}{4} \indexentry{namespaces}{5} \indexentry{lexical structure}{7} \indexentry{Unicode character set}{7} \indexentry{ASCII character set}{7} \indexentry{program@{\it program}}{9} \indexentry{lexeme@{\it lexeme}}{9} \indexentry{literal@{\it literal}}{9} \indexentry{special@{\it special}}{9} \indexentry{whitespace@{\it whitespace}}{9} \indexentry{whitestuff@{\it whitestuff}}{9} \indexentry{whitechar@{\it whitechar}}{9} \indexentry{uniWhite@{\it uniWhite}}{9} \indexentry{newline@{\it newline}}{9} \indexentry{space@{\it space}}{9} \indexentry{tab@{\it tab}}{9} \indexentry{vertab@{\it vertab}}{9} \indexentry{formfeed@{\it formfeed}}{9} \indexentry{comment@{\it comment}}{9} \indexentry{dashes@{\it dashes}}{9} \indexentry{ncomment@{\it ncomment}}{9} \indexentry{opencom@{\it opencom}}{9} \indexentry{closecom@{\it closecom}}{9} \indexentry{ANYseq@{\it ANYseq}}{9} \indexentry{ANY@{\it ANY}}{9} \indexentry{any@{\it any}}{9} \indexentry{graphic@{\it graphic}}{9} \indexentry{small@{\it small}}{9} \indexentry{ascSmall@{\it ascSmall}}{9} \indexentry{uniSmall@{\it uniSmall}}{9} \indexentry{uniDigit@{\it uniDigit}}{9} \indexentry{large@{\it large}}{9} \indexentry{ascLarge@{\it ascLarge}}{9} \indexentry{uniLarge@{\it uniLarge}}{9} \indexentry{symbol@{\it symbol}}{9} \indexentry{ascSymbol@{\it ascSymbol}}{9} \indexentry{uniSymbol@{\it uniSymbol}}{9} \indexentry{digit@{\it digit}}{9} \indexentry{ascDigit@{\it ascDigit}}{9} \indexentry{uniDigit@{\it uniDigit}}{9} \indexentry{octit@{\it octit}}{9} \indexentry{hexit@{\it hexit}}{9} \indexentry{maximal munch rule}{9} \indexentry{comment}{9} \indexentry{comment!end-of-line}{9} \indexentry{comment!nested}{9} \indexentry{identifier}{9} \indexentry{operator}{9} \indexentry{varid@{\it varid}}{10} \indexentry{conid@{\it conid}}{10} \indexentry{reservedid@{\it reservedid}}{10} \indexentry{varsym@{\it varsym}}{10} \indexentry{consym@{\it consym}}{10} \indexentry{reservedop@{\it reservedop}}{10} \indexentry{operator}{10} \indexentry{section}{10} \indexentry{namespaces}{10} \indexentry{varid@{\it varid}}{11} \indexentry{conid@{\it conid}}{11} \indexentry{tyvar@{\it tyvar}}{11} \indexentry{tycon@{\it tycon}}{11} \indexentry{tycls@{\it tycls}}{11} \indexentry{modid@{\it modid}}{11} \indexentry{qualified name}{11} \indexentry{qvarid@{\it qvarid}}{11} \indexentry{qconid@{\it qconid}}{11} \indexentry{qtycon@{\it qtycon}}{11} \indexentry{qtycls@{\it qtycls}}{11} \indexentry{qvarsym@{\it qvarsym}}{11} \indexentry{qconsym@{\it qconsym}}{11} \indexentry{number!literal syntax}{11} \indexentry{decimal@{\it decimal}}{11} \indexentry{octal@{\it octal}}{11} \indexentry{hexadecimal@{\it hexadecimal}}{11} \indexentry{integer@{\it integer}}{12} \indexentry{float@{\it float}}{12} \indexentry{character!literal syntax}{12} \indexentry{string!literal syntax}{12} \indexentry{char@{\it char}}{12} \indexentry{string@{\it string}}{12} \indexentry{escape@{\it escape}}{12} \indexentry{charesc@{\it charesc}}{12} \indexentry{ascii@{\it ascii}}{12} \indexentry{cntrl@{\it cntrl}}{12} \indexentry{gap@{\it gap}}{12} \indexentry{\\a@{\tt {\char'134}a}}{12} \indexentry{\\b@{\tt {\char'134}b}}{12} \indexentry{\\f@{\tt {\char'134}f}}{12} \indexentry{\\n@{\tt {\char'134}n}}{12} \indexentry{\\r@{\tt {\char'134}r}}{12} \indexentry{\\t@{\tt {\char'134}t}}{12} \indexentry{\\v@{\tt {\char'134}v}}{12} \indexentry{\\\&@{\tt {\char'134}\&}}{12} \indexentry{Unicode character set}{12} \indexentry{maximal munch rule}{12} \indexentry{layout}{13} \indexentry{off-side rule}{13} \indexentry{expression}{15} \indexentry{exp@{\it exp}}{16} \indexentry{exp@\mbox{$\it exp^i$}}{16} \indexentry{lexp@\mbox{$\it lexp^i$}}{16} \indexentry{rexp@\mbox{$\it rexp^i$}}{16} \indexentry{aexp@{\it aexp}}{16} \indexentry{fexp@{\it fexp}}{16} \indexentry{negation}{16} \indexentry{error}{17} \indexentry{\mbox{$\it \bot$}}{17} \indexentry{error@{\tt error}}{17} \indexentry{undefined@{\tt undefined}}{17} \indexentry{var@{\it var}}{17} \indexentry{con@{\it con}}{17} \indexentry{varop@{\it varop}}{17} \indexentry{conop@{\it conop}}{17} \indexentry{op@{\it op}}{17} \indexentry{gcon@{\it gcon}}{18} \indexentry{var@{\it var}}{18} \indexentry{qvar@{\it qvar}}{18} \indexentry{con@{\it con}}{18} \indexentry{qcon@{\it qcon}}{18} \indexentry{varop@{\it varop}}{18} \indexentry{qvarop@{\it qvarop}}{18} \indexentry{conop@{\it conop}}{18} \indexentry{qconop@{\it qconop}}{18} \indexentry{qop@{\it qop}}{18} \indexentry{gconsym@{\it gconsym}}{18} \indexentry{fixity}{18} \indexentry{number!translation of literals}{18} \indexentry{fromInteger@{\tt fromInteger}}{18} \indexentry{fromRational@{\tt fromRational}}{18} \indexentry{Num@{\tt Num} (class)}{18} \indexentry{Fractional@{\tt Fractional} (class)}{18} \indexentry{lambda abstraction}{19} \indexentry{application}{19} \indexentry{exp@{\it exp}}{19} \indexentry{fexp@{\it fexp}}{19} \indexentry{application}{19} \indexentry{linearity}{19} \indexentry{linear pattern}{19} \indexentry{operator application}{19} \indexentry{exp@{\it exp}}{19} \indexentry{qop@{\it qop}}{19} \indexentry{operator}{19} \indexentry{negation}{19} \indexentry{negate@{\tt negate}}{19} \indexentry{section}{20} \indexentry{aexp@{\it aexp}}{20} \indexentry{negation}{20} \indexentry{conditional expression}{21} \indexentry{exp@{\it exp}}{21} \indexentry{conditional expression}{21} \indexentry{aexp@{\it aexp}}{21} \indexentry{list}{21} \indexentry{aexp@{\it aexp}}{22} \indexentry{tuple}{22} \indexentry{unit expression}{22} \indexentry{aexp@{\it aexp}}{22} \indexentry{trivial type}{22} \indexentry{aexp@{\it aexp}}{23} \indexentry{arithmetic sequence}{23} \indexentry{list comprehension}{23} \indexentry{let expression!in list comprehensions}{23} \indexentry{aexp@{\it aexp}}{23} \indexentry{qual@{\it qual}}{23} \indexentry{qualifier}{23} \indexentry{generator}{23} \indexentry{guard}{23} \indexentry{let expression}{24} \indexentry{exp@{\it exp}}{24} \indexentry{declaration!within a {\tt let} expression}{24} \indexentry{irrefutable pattern}{24} \indexentry{exp@{\it exp}}{25} \indexentry{alts@{\it alts}}{25} \indexentry{alt@{\it alt}}{25} \indexentry{gdpat@{\it gdpat}}{25} \indexentry{gd@{\it gd}}{25} \indexentry{case expression}{25} \indexentry{pattern}{25} \indexentry{guard}{25} \indexentry{do expression}{26} \indexentry{let expression!in do expressions}{26} \indexentry{monad}{26} \indexentry{exp@{\it exp}}{26} \indexentry{stmt@{\it stmt}}{26} \indexentry{stmts@{\it stmts}}{26} \indexentry{Monad@{\tt Monad} (class)}{27} \indexentry{data declaration@{\tt data} declaration}{27} \indexentry{label}{27} \indexentry{field label|see{label}}{27} \indexentry{field label!selection}{27} \indexentry{field label!construction}{28} \indexentry{fbind@{\it fbind}}{28} \indexentry{field label!update}{29} \indexentry{expression type-signature}{30} \indexentry{exp@{\it exp}}{30} \indexentry{::@{\tt ::}}{30} \indexentry{pattern-matching}{30} \indexentry{pattern}{30} \indexentry{pat@{\it pat}}{31} \indexentry{pat@\mbox{$\it pat^i$}}{31} \indexentry{lpat@\mbox{$\it lpat^i$}}{31} \indexentry{rpat@\mbox{$\it rpat^i$}}{31} \indexentry{apat@{\it apat}}{31} \indexentry{fpats@{\it fpats}}{31} \indexentry{fpat@{\it fpat}}{31} \indexentry{linearity}{31} \indexentry{linear pattern}{31} \indexentry{as-pattern ({\tt {\char'100}})}{31} \indexentry{wildcard pattern ({\tt {\char'137}})}{31} \indexentry{newtype declaration@{\tt newtype} declaration}{32} \indexentry{literal pattern}{32} \indexentry{n+k pattern@\mbox{$\it n\makebox{\tt +}k$} pattern}{32} \indexentry{as-pattern ({\tt {\char'100}})}{33} \indexentry{integer literal pattern}{33} \indexentry{floating literal pattern}{33} \indexentry{n+k pattern@\mbox{$\it n\makebox{\tt +}k$} pattern}{33} \indexentry{irrefutable pattern}{33} \indexentry{refutable pattern}{33} \indexentry{newtype declaration@{\tt newtype} declaration}{33} \indexentry{guard}{34} \indexentry{irrefutable pattern}{34} \indexentry{newtype declaration@{\tt newtype} declaration}{34} \indexentry{pattern-matching!overloaded constant}{34} \indexentry{monomorphic type variable}{34} \indexentry{declaration}{37} \indexentry{binding}{37} \indexentry{vars@{\it vars}}{38} \indexentry{fixity@{\it fixity}}{38} \indexentry{ops@{\it ops}}{38} \indexentry{topdecls@{\it topdecls}}{38} \indexentry{topdecl@{\it topdecl}}{38} \indexentry{gendecl@{\it gendecl}}{38} \indexentry{decls@{\it decls}}{38} \indexentry{decl@{\it decl}}{38} \indexentry{cdecls@{\it cdecls}}{38} \indexentry{cdecl@{\it cdecl}}{38} \indexentry{idecls@{\it idecls}}{38} \indexentry{idecl@{\it idecl}}{38} \indexentry{Hindley-Milner type system}{38} \indexentry{class}{38} \indexentry{type class}{38} \indexentry{constructor class}{38} \indexentry{overloaded functions}{38} \indexentry{class method}{38} \indexentry{class method}{39} \indexentry{kind}{39} \indexentry{type}{39} \indexentry{type@{\it type}}{40} \indexentry{atype@{\it atype}}{40} \indexentry{btype@{\it btype}}{40} \indexentry{gtycon@{\it gtycon}}{40} \indexentry{type expression}{40} \indexentry{constructor expression}{40} \indexentry{trivial type}{40} \indexentry{function type}{40} \indexentry{list}{40} \indexentry{tuple}{40} \indexentry{kind}{40} \indexentry{kind inference}{40} \indexentry{function type}{41} \indexentry{tuple type}{41} \indexentry{list type}{41} \indexentry{quantification}{41} \indexentry{class assertion}{41} \indexentry{context}{41} \indexentry{context@{\it context}}{41} \indexentry{class@{\it class}}{41} \indexentry{simpleclass@{\it simpleclass}}{41} \indexentry{tycls@{\it tycls}}{41} \indexentry{tyvar@{\it tyvar}}{41} \indexentry{type}{42} \indexentry{type environment}{42} \indexentry{class environment}{42} \indexentry{generalization preorder}{42} \indexentry{principal type}{42} \indexentry{type signature}{42} \indexentry{datatype}{43} \indexentry{algebraic datatype}{43} \indexentry{topdecl@{\em topdecl} (\mbox{\tt data})}{43} \indexentry{simpletype@{\it simpletype}}{43} \indexentry{constrs@{\it constrs}}{43} \indexentry{constr@{\it constr}}{43} \indexentry{fielddecl@{\it fielddecl}}{43} \indexentry{deriving@{\it deriving}}{43} \indexentry{dclass@{\it dclass}}{43} \indexentry{data declaration@{\tt data} declaration}{43} \indexentry{precedence}{43} \indexentry{data constructor}{43} \indexentry{type constructor}{43} \indexentry{kind}{44} \indexentry{kind inference}{44} \indexentry{abstract datatype}{44} \indexentry{field label}{44} \indexentry{strictness flag}{45} \indexentry{"!@{\tt {\char'041}}}{45} \indexentry{type synonym}{45} \indexentry{topdecl@{\em topdecl} (\mbox{\tt type})}{45} \indexentry{simpletype@{\it simpletype}}{45} \indexentry{kind}{45} \indexentry{kind inference}{45} \indexentry{recursive datatype}{46} \indexentry{type synonym!recursive}{46} \indexentry{newtype declaration@{\tt newtype} declaration}{46} \indexentry{topdecl@{\em topdecl} (\mbox{\tt newtype})}{46} \indexentry{simpletype@{\it simpletype}}{46} \indexentry{newconstr@{\it newconstr}}{46} \indexentry{class}{47} \indexentry{overloading}{47} \indexentry{class declaration}{47} \indexentry{topdecl@{\em topdecl} (\mbox{\tt class})}{47} \indexentry{gendecl@{\it gendecl}}{47} \indexentry{cdecls@{\it cdecls}}{47} \indexentry{cdecl@{\it cdecl}}{47} \indexentry{declaration!within a {\tt class} declaration}{47} \indexentry{superclass}{48} \indexentry{superclass}{48} \indexentry{class method}{48} \indexentry{fixity declaration}{48} \indexentry{default class method}{48} \indexentry{class declaration!with an empty \mbox{\tt where} part}{48} \indexentry{superclass}{49} \indexentry{instance declaration!with an empty \mbox{\tt where} part}{49} \indexentry{instance declaration}{49} \indexentry{topdecl@{\em topdecl} (\mbox{\tt instance})}{49} \indexentry{inst@{\it inst}}{49} \indexentry{valdefs@{\it valdefs}}{49} \indexentry{gtycon@{\it gtycon}}{49} \indexentry{idecl@{\it idecl}}{49} \indexentry{idecls@{\it idecls}}{49} \indexentry{declaration!within an {\tt instance} declaration}{49} \indexentry{type synonym}{49} \indexentry{class method}{49} \indexentry{type signature}{49} \indexentry{fixity declaration}{49} \indexentry{default class method}{50} \indexentry{default class method}{50} \indexentry{instance declaration}{50} \indexentry{kind}{50} \indexentry{kind inference}{50} \indexentry{derived instance}{51} \indexentry{Eq@{\tt Eq} (class)!derived instance}{51} \indexentry{Ord@{\tt Ord} (class)!derived instance}{51} \indexentry{Enum@{\tt Enum} (class)!derived instance}{51} \indexentry{Bounded@{\tt Bounded} (class)!derived instance}{51} \indexentry{Show@{\tt Show} (class)!derived instance}{51} \indexentry{Read@{\tt Read} (class)!derived instance}{51} \indexentry{Enum@{\tt Enum} (class)}{51} \indexentry{default declaration@{\tt default} declaration}{51} \indexentry{overloading!defaults}{51} \indexentry{topdecl@{\em topdecl} (\mbox{\tt default})}{51} \indexentry{ambiguous type}{51} \indexentry{expression type-signature}{52} \indexentry{Num@{\tt Num} (class)}{52} \indexentry{type signature}{53} \indexentry{signdecl@{\it signdecl}}{53} \indexentry{vars@{\it vars}}{53} \indexentry{principal type}{53} \indexentry{polymorphic recursion}{54} \indexentry{fixity declaration}{54} \indexentry{gendecl@{\it gendecl}}{54} \indexentry{fixity@{\it fixity}}{54} \indexentry{ops@{\it ops}}{54} \indexentry{op@{\it op}}{54} \indexentry{"!"!@{\tt {\char'041}{\char'041}}}{55} \indexentry{.@{\tt .}}{55} \indexentry{**@{\tt **}}{55} \indexentry{^@{\tt {\char'136}}}{55} \indexentry{^^@{\tt {\char'136}{\char'136}}}{55} \indexentry{*@{\tt *}}{55} \indexentry{/@{\tt /}}{55} \indexentry{div@{\tt div}}{55} \indexentry{mod@{\tt mod}}{55} \indexentry{rem@{\tt rem}}{55} \indexentry{+@{\tt +}}{55} \indexentry{-@{\tt -}}{55} \indexentry{:@{\tt :}}{55} \indexentry{++@{\tt ++}}{55} \indexentry{/=@{\tt /=}}{55} \indexentry{<@{\tt <}}{55} \indexentry{<=@{\tt <=}}{55} \indexentry{==@{\tt ==}}{55} \indexentry{>@{\tt >}}{55} \indexentry{>=@{\tt >=}}{55} \indexentry{elem@{\tt elem}}{55} \indexentry{notElem@{\tt notElem}}{55} \indexentry{&&@{\tt \&\&}}{55} \indexentry{"|"|@{\tt {\char'174}{\char'174}}}{55} \indexentry{>>@{\tt >>}}{55} \indexentry{>>=@{\tt >>=}}{55} \indexentry{$@{\tt {\char'044}}}{55} \indexentry{function binding}{55} \indexentry{pattern binding}{55} \indexentry{decl@{\it decl}}{56} \indexentry{rhs@{\it rhs}}{56} \indexentry{gdrhs@{\it gdrhs}}{56} \indexentry{gd@{\it gd}}{56} \indexentry{function binding}{56} \indexentry{linearity}{56} \indexentry{linear pattern}{56} \indexentry{pattern binding}{57} \indexentry{simple pattern binding}{57} \indexentry{irrefutable pattern}{57} \indexentry{n+k pattern@\mbox{$\it n\makebox{\tt +}k$} pattern}{57} \indexentry{Hindley-Milner type system}{58} \indexentry{dependency analysis}{58} \indexentry{declaration group}{58} \indexentry{generalization}{59} \indexentry{context reduction}{59} \indexentry{monomorphic type variable}{60} \indexentry{monomorphic type variable}{61} \indexentry{monomorphism restriction}{61} \indexentry{simple pattern binding}{62} \indexentry{ambiguous type}{62} \indexentry{simple pattern binding}{62} \indexentry{kind}{64} \indexentry{kind inference}{64} \indexentry{module}{65} \indexentry{entity}{65} \indexentry{Main@{\tt Main} (module)}{65} \indexentry{main@{\tt main}}{65} \indexentry{module@{\it module}}{66} \indexentry{body@{\it body}}{66} \indexentry{modid@{\it modid}}{66} \indexentry{impdecls@{\it impdecls}}{66} \indexentry{topdecls@{\it topdecls}}{66} \indexentry{abbreviated module}{66} \indexentry{export list}{66} \indexentry{exports@{\it exports}}{67} \indexentry{export@{\it export}}{67} \indexentry{algebraic datatype}{67} \indexentry{type synonym}{67} \indexentry{class declaration}{67} \indexentry{import declaration}{69} \indexentry{impdecl@{\it impdecl}}{69} \indexentry{impspec@{\it impspec}}{69} \indexentry{import@{\it import}}{69} \indexentry{cname@{\it cname}}{69} \indexentry{hiding}{70} \indexentry{qualified name}{70} \indexentry{instance declaration!importing and exporting}{71} \indexentry{qualified name}{72} \indexentry{closure}{74} \indexentry{standard prelude}{74} \indexentry{libraries}{74} \indexentry{Prelude@{\tt Prelude} (module)}{75} \indexentry{Prelude@{\tt Prelude} (module)}{75} \indexentry{Prelude!implicit import of}{75} \indexentry{separate compilation}{76} \indexentry{abstract datatype}{76} \indexentry{boolean}{79} \indexentry{Bool@{\tt Bool} (datatype)}{79} \indexentry{False@{\tt False}}{79} \indexentry{True@{\tt True}}{79} \indexentry{"|"|@{\tt {\char'174}{\char'174}}}{79} \indexentry{&&@{\tt \&\&}}{79} \indexentry{not@{\tt not}}{79} \indexentry{otherwise@{\tt otherwise}}{79} \indexentry{character}{79} \indexentry{string}{79} \indexentry{Char@{\tt Char} (datatype)}{79} \indexentry{String@{\tt String} (type synonym)}{80} \indexentry{list}{80} \indexentry{[]@{\tt []} (nil)}{80} \indexentry{:@{\tt :}}{80} \indexentry{arithmetic sequence}{80} \indexentry{list comprehension}{80} \indexentry{tuple}{80} \indexentry{(,)@{\tt (,)}}{80} \indexentry{(,,)@{\tt (,,)}}{80} \indexentry{fst@{\tt fst}}{80} \indexentry{snd@{\tt snd}}{80} \indexentry{curry@{\tt curry}}{80} \indexentry{uncurry@{\tt uncurry}}{80} \indexentry{zip@{\tt zip}}{80} \indexentry{trivial type}{81} \indexentry{function}{81} \indexentry{id@{\tt id}}{81} \indexentry{const@{\tt const}}{81} \indexentry{.@{\tt .}}{81} \indexentry{flip@{\tt flip}}{81} \indexentry{until@{\tt until}}{81} \indexentry{IO@{\tt IO} (datatype)}{81} \indexentry{IOError@{\tt IOError} (datatype)}{81} \indexentry{Just@{\tt Just}}{81} \indexentry{Nothing@{\tt Nothing}}{81} \indexentry{Maybe@{\tt Maybe} (datatype)}{81} \indexentry{Left@{\tt Left}}{81} \indexentry{Right@{\tt Right}}{81} \indexentry{Either@{\tt Either} (datatype)}{81} \indexentry{LT@{\tt LT}}{81} \indexentry{EQ@{\tt EQ}}{81} \indexentry{GT@{\tt GT}}{81} \indexentry{Ordering@{\tt Ordering} (datatype)}{81} \indexentry{maybe@{\tt maybe}}{81} \indexentry{either@{\tt either}}{81} \indexentry{$"!@{\tt {\char'044}{\char'041}}}{81} \indexentry{$@{\tt {\char'044}}}{81} \indexentry{seq@{\tt seq}}{81} \indexentry{strictness flags}{82} \indexentry{Eq@{\tt Eq} (class)}{82} \indexentry{==@{\tt ==}}{82} \indexentry{/=@{\tt /=}}{82} \indexentry{Ord@{\tt Ord} (class)}{84} \indexentry{<@{\tt <}}{84} \indexentry{<=@{\tt <=}}{84} \indexentry{>@{\tt >}}{84} \indexentry{>=@{\tt >=}}{84} \indexentry{compare@{\tt compare}}{84} \indexentry{max@{\tt max}}{84} \indexentry{min@{\tt min}}{84} \indexentry{ReadS@{\tt ReadS} (type synonym)}{85} \indexentry{ShowS@{\tt ShowS} (type synonym)}{85} \indexentry{Read@{\tt Read} (class)}{85} \indexentry{Show@{\tt Show} (class)}{85} \indexentry{show@{\tt show}}{85} \indexentry{readsPrec@{\tt readsPrec}}{85} \indexentry{showsPrec@{\tt showsPrec}}{85} \indexentry{readList@{\tt readList}}{85} \indexentry{showList@{\tt showList}}{85} \indexentry{reads@{\tt reads}}{85} \indexentry{shows@{\tt shows}}{85} \indexentry{read@{\tt read}}{85} \indexentry{shows@{\tt shows}}{86} \indexentry{reads@{\tt reads}}{86} \indexentry{show@{\tt show}}{86} \indexentry{read@{\tt read}}{86} \indexentry{lex@{\tt lex}}{86} \indexentry{Enum@{\tt Enum} (class)}{86} \indexentry{toEnum@{\tt toEnum}}{86} \indexentry{fromEnum@{\tt fromEnum}}{86} \indexentry{enumFrom@{\tt enumFrom}}{86} \indexentry{enumFromThen@{\tt enumFromThen}}{86} \indexentry{enumFromTo@{\tt enumFromTo}}{86} \indexentry{enumFromThenTo@{\tt enumFromThenTo}}{86} \indexentry{Functor@{\tt Functor} (class)}{87} \indexentry{fmap@{\tt fmap}}{87} \indexentry{functor}{87} \indexentry{Monad@{\tt Monad} (class)}{88} \indexentry{return@{\tt return}}{88} \indexentry{fail@{\tt fail}}{88} \indexentry{>>@{\tt >>}}{88} \indexentry{>>=@{\tt >>=}}{88} \indexentry{monad}{88} \indexentry{sequence@{\tt sequence}}{88} \indexentry{sequence{\char '137}@{\tt sequence{\char '137}}}{88} \indexentry{mapM{\char '137}@{\tt mapM{\char '137}}}{88} \indexentry{mapM@{\tt mapM}}{88} \indexentry{=<<@{\tt =<<}}{88} \indexentry{Bounded@{\tt Bounded} (class)}{89} \indexentry{minBound@{\tt minBound}}{89} \indexentry{maxBound@{\tt maxBound}}{89} \indexentry{number}{89} \indexentry{Num@{\tt Num} (class)}{89} \indexentry{Eq@{\tt Eq} (class)}{89} \indexentry{Real@{\tt Real} (class)}{89} \indexentry{Ord@{\tt Ord} (class)}{89} \indexentry{Integral@{\tt Integral} (class)}{89} \indexentry{Fractional@{\tt Fractional} (class)}{89} \indexentry{Floating@{\tt Floating} (class)}{89} \indexentry{Int@{\tt Int} (datatype)}{89} \indexentry{Float@{\tt Float} (datatype)}{89} \indexentry{Double@{\tt Double} (datatype)}{89} \indexentry{numeric type}{90} \indexentry{fromInteger@{\tt fromInteger}}{90} \indexentry{fromRational@{\tt fromRational}}{90} \indexentry{fromInteger@{\tt fromInteger}}{90} \indexentry{fromRational@{\tt fromRational}}{90} \indexentry{arithmetic operator}{90} \indexentry{+@{\tt +}}{90} \indexentry{*@{\tt *}}{90} \indexentry{-@{\tt -}}{90} \indexentry{negate@{\tt negate}}{90} \indexentry{quot@{\tt quot}}{90} \indexentry{rem@{\tt rem}}{90} \indexentry{div@{\tt div}}{90} \indexentry{mod@{\tt mod}}{90} \indexentry{/@{\tt /}}{90} \indexentry{Num@{\tt Num} (class)}{91} \indexentry{+@{\tt +}}{91} \indexentry{-@{\tt -}}{91} \indexentry{*@{\tt *}}{91} \indexentry{negate@{\tt negate}}{91} \indexentry{abs@{\tt abs}}{91} \indexentry{signum@{\tt signum}}{91} \indexentry{fromInteger@{\tt fromInteger}}{91} \indexentry{Real@{\tt Real} (class)}{91} \indexentry{toRational@{\tt toRational}}{91} \indexentry{Integral@{\tt Integral} (class)}{91} \indexentry{quotRem@{\tt quotRem}}{91} \indexentry{divMod@{\tt divMod}}{91} \indexentry{mod@{\tt mod}}{91} \indexentry{div@{\tt div}}{91} \indexentry{rem@{\tt rem}}{91} \indexentry{quot@{\tt quot}}{91} \indexentry{even@{\tt even}}{91} \indexentry{odd@{\tt odd}}{91} \indexentry{Fractional@{\tt Fractional} (class)}{91} \indexentry{/@{\tt /}}{91} \indexentry{recip@{\tt recip}}{91} \indexentry{fromRational@{\tt fromRational}}{91} \indexentry{Floating@{\tt Floating} (class)}{91} \indexentry{pi@{\tt pi}}{91} \indexentry{exp@{\tt exp}}{91} \indexentry{log@{\tt log}}{91} \indexentry{sqrt@{\tt sqrt}}{91} \indexentry{**@{\tt **}}{91} \indexentry{logBase@{\tt logBase}}{91} \indexentry{sin@{\tt sin}}{91} \indexentry{cos@{\tt cos}}{91} \indexentry{tan@{\tt tan}}{91} \indexentry{asin@{\tt asin}}{91} \indexentry{acos@{\tt acos}}{91} \indexentry{atan@{\tt atan}}{91} \indexentry{sinh@{\tt sinh}}{91} \indexentry{cosh@{\tt cosh}}{91} \indexentry{tanh@{\tt tanh}}{91} \indexentry{asinh@{\tt asinh}}{91} \indexentry{acosh@{\tt acosh}}{91} \indexentry{atanh@{\tt atanh}}{91} \indexentry{even@{\tt even}}{91} \indexentry{odd@{\tt odd}}{91} \indexentry{gcd@{\tt gcd}}{91} \indexentry{lcm@{\tt lcm}}{91} \indexentry{exponentiation}{91} \indexentry{logarithm}{91} \indexentry{exp@{\tt exp}}{91} \indexentry{log@{\tt log}}{91} \indexentry{logBase@{\tt logBase}}{91} \indexentry{sqrt@{\tt sqrt}}{91} \indexentry{^@{\tt {\char'136}}}{91} \indexentry{^^@{\tt {\char'136}{\char'136}}}{91} \indexentry{**@{\tt **}}{91} \indexentry{RealFrac@{\tt RealFrac} (class)}{92} \indexentry{properFraction@{\tt properFraction}}{92} \indexentry{approxRational@{\tt approxRational}}{92} \indexentry{truncate@{\tt truncate}}{92} \indexentry{round@{\tt round}}{92} \indexentry{ceiling@{\tt ceiling}}{92} \indexentry{floor@{\tt floor}}{92} \indexentry{RealFloat@{\tt RealFloat} (class)}{92} \indexentry{floatRadix@{\tt floatRadix}}{92} \indexentry{floatDigits@{\tt floatDigits}}{92} \indexentry{floatRange@{\tt floatRange}}{92} \indexentry{decodeFloat@{\tt decodeFloat}}{92} \indexentry{encodeFloat@{\tt encodeFloat}}{92} \indexentry{exponent@{\tt exponent}}{92} \indexentry{significand@{\tt significand}}{92} \indexentry{scaleFloat@{\tt scaleFloat}}{92} \indexentry{Int@{\tt Int} (datatype)}{92} \indexentry{Integer@{\tt Integer} (datatype)}{92} \indexentry{fromIntegral@{\tt fromIntegral}}{92} \indexentry{gcd@{\tt gcd}}{92} \indexentry{lcm@{\tt lcm}}{92} \indexentry{^@{\tt {\char'136}}}{92} \indexentry{^^@{\tt {\char'136}{\char'136}}}{92} \indexentry{RealFrac@{\tt RealFrac} (class)}{92} \indexentry{Float@{\tt Float} (datatype)}{92} \indexentry{Double@{\tt Double} (datatype)}{92} \indexentry{realToFrac@{\tt realToFrac}}{92} \indexentry{atan2@{\tt atan2}}{92} \indexentry{magnitude}{92} \indexentry{sign}{92} \indexentry{abs@{\tt abs}}{92} \indexentry{signum@{\tt signum}}{92} \indexentry{trigonometric function}{93} \indexentry{sine}{93} \indexentry{cosine}{93} \indexentry{tangent}{93} \indexentry{atan2@{\tt atan2}}{93} \indexentry{atan2@{\tt atan2}}{93} \indexentry{coercion}{93} \indexentry{ceiling@{\tt ceiling}}{93} \indexentry{floor@{\tt floor}}{93} \indexentry{truncate@{\tt truncate}}{93} \indexentry{round@{\tt round}}{93} \indexentry{properFraction@{\tt properFraction}}{93} \indexentry{toRational@{\tt toRational}}{93} \indexentry{approxRational@{\tt approxRational}}{93} \indexentry{RealFloat@{\tt RealFloat} (class)}{93} \indexentry{floatRadix@{\tt floatRadix}}{93} \indexentry{floatDigits@{\tt floatDigits}}{93} \indexentry{floatRange@{\tt floatRange}}{93} \indexentry{decodeFloat@{\tt decodeFloat}}{93} \indexentry{encodeFloat@{\tt encodeFloat}}{93} \indexentry{significand@{\tt significand}}{94} \indexentry{exponent@{\tt exponent}}{94} \indexentry{fromIntegral@{\tt fromIntegral}}{94} \indexentry{realToFrac@{\tt realToFrac}}{94} \indexentry{basic input/output}{95} \indexentry{monad}{95} \indexentry{putChar@{\tt putChar}}{96} \indexentry{putStr@{\tt putStr}}{96} \indexentry{putStrLn@{\tt putStrLn}}{96} \indexentry{print@{\tt print}}{96} \indexentry{interact@{\tt interact}}{96} \indexentry{readIO@{\tt readIO}}{96} \indexentry{readLn@{\tt readLn}}{96} \indexentry{getChar@{\tt getChar}}{96} \indexentry{getLine@{\tt getLine}}{96} \indexentry{getContents@{\tt getContents}}{96} \indexentry{writeFile@{\tt writeFile}}{97} \indexentry{readFile@{\tt readFile}}{97} \indexentry{appendFile@{\tt appendFile}}{97} \indexentry{FilePath@{\tt FilePath} (type synonym)}{97} \indexentry{>>@{\tt >>}}{97} \indexentry{>>=@{\tt >>=}}{97} \indexentry{do expression}{97} \indexentry{exception handling}{98} \indexentry{userError@{\tt userError}}{98} \indexentry{ioError@{\tt ioError}}{98} \indexentry{catch@{\tt catch}}{98} \indexentry{fail@{\tt fail}}{99} \indexentry{Prelude@{\tt Prelude} (module)}{103} \indexentry{PreludeList@{\tt PreludeList} (module)}{103} \indexentry{PreludeBuiltin@{\tt PreludeBuiltin} (module)}{103} \indexentry{UnicodePrims@{\tt UnicodePrims} (module)}{103} \indexentry{PreludeList@{\tt PreludeList} (module)}{103} \indexentry{PreludeText@{\tt PreludeText} (module)}{103} \indexentry{PreludeIO@{\tt PreludeIO} (module)}{103} \indexentry{Ratio@{\tt Ratio} (module)}{103} \indexentry{.@{\tt .}}{104} \indexentry{^@{\tt {\char'136}}}{104} \indexentry{^^@{\tt {\char'136}{\char'136}}}{104} \indexentry{**@{\tt **}}{104} \indexentry{*@{\tt *}}{104} \indexentry{/@{\tt /}}{104} \indexentry{quot@{\tt quot}}{104} \indexentry{rem@{\tt rem}}{104} \indexentry{div@{\tt div}}{104} \indexentry{mod@{\tt mod}}{104} \indexentry{+@{\tt +}}{104} \indexentry{-@{\tt -}}{104} \indexentry{==@{\tt ==}}{104} \indexentry{/=@{\tt /=}}{104} \indexentry{<@{\tt <}}{104} \indexentry{<=@{\tt <=}}{104} \indexentry{>=@{\tt >=}}{104} \indexentry{>@{\tt >}}{104} \indexentry{&&@{\tt \&\&}}{104} \indexentry{"|"|@{\tt {\char'174}{\char'174}}}{104} \indexentry{>>@{\tt >>}}{104} \indexentry{>>=@{\tt >>=}}{104} \indexentry{=<<@{\tt =<<}}{104} \indexentry{$@{\tt {\char'044}}}{104} \indexentry{$"!@{\tt {\char'044}{\char'041}}}{104} \indexentry{seq@{\tt seq}}{104} \indexentry{==@{\tt ==}}{104} \indexentry{/=@{\tt /=}}{104} \indexentry{Eq@{\tt Eq} (class)}{104} \indexentry{compare@{\tt compare}}{104} \indexentry{<@{\tt <}}{104} \indexentry{<=@{\tt <=}}{104} \indexentry{>=@{\tt >=}}{104} \indexentry{>@{\tt >}}{104} \indexentry{max@{\tt max}}{104} \indexentry{min@{\tt min}}{104} \indexentry{Ord@{\tt Ord} (class)}{104} \indexentry{Eq@{\tt Eq} (class)!superclass of {\tt Ord}}{104} \indexentry{succ@{\tt succ}}{105} \indexentry{pred@{\tt pred}}{105} \indexentry{toEnum@{\tt toEnum}}{105} \indexentry{fromEnum@{\tt fromEnum}}{105} \indexentry{enumFrom@{\tt enumFrom}}{105} \indexentry{enumFromThen@{\tt enumFromThen}}{105} \indexentry{enumFromTo@{\tt enumFromTo}}{105} \indexentry{enumFromThenTo@{\tt enumFromThenTo}}{105} \indexentry{Enum@{\tt Enum} (class)}{105} \indexentry{minBound@{\tt minBound}}{105} \indexentry{maxBound@{\tt maxBound}}{105} \indexentry{Bounded@{\tt Bounded} (class)}{105} \indexentry{+@{\tt +}}{105} \indexentry{-@{\tt -}}{105} \indexentry{*@{\tt *}}{105} \indexentry{negate@{\tt negate}}{105} \indexentry{abs@{\tt abs}}{105} \indexentry{signum@{\tt signum}}{105} \indexentry{fromInteger@{\tt fromInteger}}{105} \indexentry{Num@{\tt Num} (class)}{105} \indexentry{Eq@{\tt Eq} (class)!superclass of {\tt Num}}{105} \indexentry{Show@{\tt Show} (class)!superclass of {\tt Num}}{105} \indexentry{toRational@{\tt toRational}}{105} \indexentry{Real@{\tt Real} (class)}{105} \indexentry{Num@{\tt Num} (class)!superclass of {\tt Real}}{105} \indexentry{Ord@{\tt Ord} (class)!superclass of {\tt Real}}{105} \indexentry{quot@{\tt quot}}{106} \indexentry{rem@{\tt rem}}{106} \indexentry{div@{\tt div}}{106} \indexentry{mod@{\tt mod}}{106} \indexentry{quotRem@{\tt quotRem}}{106} \indexentry{divMod@{\tt divMod}}{106} \indexentry{toInteger@{\tt toInteger}}{106} \indexentry{Integral@{\tt Integral} (class)}{106} \indexentry{Real@{\tt Real} (class)!superclass of {\tt Integral}}{106} \indexentry{Enum@{\tt Enum} (class)!superclass of {\tt Integral}}{106} \indexentry{/@{\tt /}}{106} \indexentry{recip@{\tt recip}}{106} \indexentry{fromRational@{\tt fromRational}}{106} \indexentry{Fractional@{\tt Fractional} (class)}{106} \indexentry{Num@{\tt Num} (class)!superclass of {\tt Fractional}}{106} \indexentry{pi@{\tt pi}}{106} \indexentry{exp@{\tt exp}}{106} \indexentry{log@{\tt log}}{106} \indexentry{sqrt@{\tt sqrt}}{106} \indexentry{**@{\tt **}}{106} \indexentry{logBase@{\tt logBase}}{106} \indexentry{sin@{\tt sin}}{106} \indexentry{cos@{\tt cos}}{106} \indexentry{tan@{\tt tan}}{106} \indexentry{asin@{\tt asin}}{106} \indexentry{acos@{\tt acos}}{106} \indexentry{atan@{\tt atan}}{106} \indexentry{sinh@{\tt sinh}}{106} \indexentry{cosh@{\tt cosh}}{106} \indexentry{tanh@{\tt tanh}}{106} \indexentry{asinh@{\tt asinh}}{106} \indexentry{acosh@{\tt acosh}}{106} \indexentry{atanh@{\tt atanh}}{106} \indexentry{Floating@{\tt Floating} (class)}{106} \indexentry{Fractional@{\tt Fractional} (class)!superclass of {\tt Floating}}{106} \indexentry{properFraction@{\tt properFraction}}{107} \indexentry{truncate@{\tt truncate}}{107} \indexentry{round@{\tt round}}{107} \indexentry{ceiling@{\tt ceiling}}{107} \indexentry{floor@{\tt floor}}{107} \indexentry{RealFrac@{\tt RealFrac} (class)}{107} \indexentry{Real@{\tt Real} (class)!superclass of {\tt RealFrac}}{107} \indexentry{Fractional@{\tt Fractional} (class)!superclass of {\tt RealFrac}}{107} \indexentry{floatRadix@{\tt floatRadix}}{108} \indexentry{floatDigits@{\tt floatDigits}}{108} \indexentry{floatRange@{\tt floatRange}}{108} \indexentry{decodeFloat@{\tt decodeFloat}}{108} \indexentry{encodeFloat@{\tt encodeFloat}}{108} \indexentry{exponent@{\tt exponent}}{108} \indexentry{significand@{\tt significand}}{108} \indexentry{scaleFloat@{\tt scaleFloat}}{108} \indexentry{atan2@{\tt atan2}}{108} \indexentry{RealFloat@{\tt RealFloat} (class)}{108} \indexentry{RealFrac@{\tt RealFrac} (class)!superclass of {\tt RealFloat}}{108} \indexentry{Floating@{\tt Floating} (class)!superclass of {\tt RealFloat}}{108} \indexentry{subtract@{\tt subtract}}{108} \indexentry{even@{\tt even}}{108} \indexentry{odd@{\tt odd}}{108} \indexentry{gcd@{\tt gcd}}{108} \indexentry{lcm@{\tt lcm}}{109} \indexentry{^@{\tt {\char'136}}}{109} \indexentry{^^@{\tt {\char'136}{\char'136}}}{109} \indexentry{fromIntegral@{\tt fromIntegral}}{109} \indexentry{realToFrac@{\tt realToFrac}}{109} \indexentry{fmap@{\tt fmap}}{109} \indexentry{Functor@{\tt Functor} (class)}{109} \indexentry{>>=@{\tt >>=}}{109} \indexentry{>>@{\tt >>}}{109} \indexentry{return@{\tt return}}{109} \indexentry{fail@{\tt fail}}{109} \indexentry{Monad@{\tt Monad} (class)}{109} \indexentry{sequence@{\tt sequence}}{109} \indexentry{sequence{\char '137}@{\tt sequence{\char '137}}}{109} \indexentry{mapM@{\tt mapM}}{109} \indexentry{mapM{\char '137}@{\tt mapM{\char '137}}}{109} \indexentry{=<<@{\tt =<<}}{109} \indexentry{id@{\tt id}}{110} \indexentry{const@{\tt const}}{110} \indexentry{.@{\tt .}}{110} \indexentry{flip@{\tt flip}}{110} \indexentry{seq@{\tt seq}}{110} \indexentry{$@{\tt {\char'044}}}{110} \indexentry{$"!@{\tt {\char'044}{\char'041}}}{110} \indexentry{Bool@{\tt Bool} (datatype)}{110} \indexentry{&&@{\tt \&\&}}{110} \indexentry{"|"|@{\tt {\char'174}{\char'174}}}{110} \indexentry{not@{\tt not}}{110} \indexentry{otherwise@{\tt otherwise}}{110} \indexentry{Char@{\tt Char} (datatype)}{110} \indexentry{Eq@{\tt Eq} (class)!instance for {\tt Char}}{110} \indexentry{Ord@{\tt Ord} (class)!instance for {\tt Char}}{111} \indexentry{Enum@{\tt Enum} (class)!instance for {\tt Char}}{111} \indexentry{Bounded@{\tt Bounded} (class)!instance for {\tt Char}}{111} \indexentry{String@{\tt String} (type synonym)}{111} \indexentry{Maybe@{\tt Maybe} (datatype)}{111} \indexentry{maybe@{\tt maybe}}{111} \indexentry{Functor@{\tt Functor} (class)!instance for {\tt Maybe}}{111} \indexentry{Monad@{\tt Monad} (class)!instance for {\tt Maybe}}{111} \indexentry{Either@{\tt Either} (datatype)}{111} \indexentry{either@{\tt either}}{111} \indexentry{IO@{\tt IO} (datatype)}{111} \indexentry{Functor@{\tt Functor} (class)!instance for {\tt IO}}{111} \indexentry{Monad@{\tt Monad} (class)!instance for {\tt IO}}{111} \indexentry{Ordering@{\tt Ordering} (datatype)}{112} \indexentry{Int@{\tt Int} (datatype)}{112} \indexentry{Integer@{\tt Integer} (datatype)}{112} \indexentry{Float@{\tt Float} (datatype)}{112} \indexentry{Double@{\tt Double} (datatype)}{112} \indexentry{Enum@{\tt Enum} (class)!instance for {\tt Float}}{113} \indexentry{Enum@{\tt Enum} (class)!instance for {\tt Double}}{113} \indexentry{numericEnumFrom@{\tt numericEnumFrom}}{113} \indexentry{numericEnumFromThen@{\tt numericEnumFromThen}}{113} \indexentry{numericEnumFromTo@{\tt numericEnumFromTo}}{113} \indexentry{numericEnumFromThenTo@{\tt numericEnumFromThenTo}}{113} \indexentry{Functor@{\tt Functor} (class)!instance for {\tt []}}{113} \indexentry{Monad@{\tt Monad} (class)!instance for {\tt []}}{113} \indexentry{fst@{\tt fst}}{114} \indexentry{snd@{\tt snd}}{114} \indexentry{curry@{\tt curry}}{114} \indexentry{uncurry@{\tt uncurry}}{114} \indexentry{until@{\tt until}}{114} \indexentry{asTypeOf@{\tt asTypeOf}}{114} \indexentry{error@{\tt error}}{114} \indexentry{undefined@{\tt undefined}}{114} \indexentry{PreludeList@{\tt PreludeList} (module)}{115} \indexentry{"!"!@{\tt {\char'041}{\char'041}}}{115} \indexentry{++@{\tt ++}}{115} \indexentry{elem@{\tt elem}}{115} \indexentry{notElem@{\tt notElem}}{115} \indexentry{map@{\tt map}}{115} \indexentry{++@{\tt ++}}{115} \indexentry{filter@{\tt filter}}{115} \indexentry{concat@{\tt concat}}{115} \indexentry{concatMap@{\tt concatMap}}{115} \indexentry{head@{\tt head}}{115} \indexentry{tail@{\tt tail}}{115} \indexentry{last@{\tt last}}{116} \indexentry{init@{\tt init}}{116} \indexentry{null@{\tt null}}{116} \indexentry{length@{\tt length}}{116} \indexentry{"!"!@{\tt {\char'041}{\char'041}}}{116} \indexentry{foldl@{\tt foldl}}{116} \indexentry{foldl1@{\tt foldl1}}{116} \indexentry{scanl@{\tt scanl}}{116} \indexentry{scanl1@{\tt scanl1}}{116} \indexentry{foldr@{\tt foldr}}{117} \indexentry{foldr1@{\tt foldr1}}{117} \indexentry{scanr@{\tt scanr}}{117} \indexentry{scanr1@{\tt scanr1}}{117} \indexentry{iterate@{\tt iterate}}{117} \indexentry{repeat@{\tt repeat}}{117} \indexentry{replicate@{\tt replicate}}{117} \indexentry{cycle@{\tt cycle}}{117} \indexentry{take@{\tt take}}{117} \indexentry{drop@{\tt drop}}{118} \indexentry{splitAt@{\tt splitAt}}{118} \indexentry{takeWhile@{\tt takeWhile}}{118} \indexentry{dropWhile@{\tt dropWhile}}{118} \indexentry{span@{\tt span}}{118} \indexentry{break@{\tt break}}{118} \indexentry{lines@{\tt lines}}{118} \indexentry{words@{\tt words}}{118} \indexentry{unlines@{\tt unlines}}{119} \indexentry{unwords@{\tt unwords}}{119} \indexentry{reverse@{\tt reverse}}{119} \indexentry{and@{\tt and}}{119} \indexentry{or@{\tt or}}{119} \indexentry{any@{\tt any}}{119} \indexentry{all@{\tt all}}{119} \indexentry{elem@{\tt elem}}{119} \indexentry{notElem@{\tt notElem}}{119} \indexentry{lookup@{\tt lookup}}{119} \indexentry{sum@{\tt sum}}{119} \indexentry{product@{\tt product}}{119} \indexentry{maximum@{\tt maximum}}{119} \indexentry{minimum@{\tt minimum}}{119} \indexentry{zip@{\tt zip}}{120} \indexentry{zip3@{\tt zip3}}{120} \indexentry{zipWith@{\tt zipWith}}{120} \indexentry{zipWith3@{\tt zipWith3}}{120} \indexentry{unzip@{\tt unzip}}{120} \indexentry{unzip3@{\tt unzip3}}{120} \indexentry{PreludeText@{\tt PreludeText} (module)}{121} \indexentry{Char@{\tt Char} (module)}{121} \indexentry{Numeric@{\tt Numeric} (module)}{121} \indexentry{ReadS@{\tt ReadS} (type synonym)}{121} \indexentry{ShowS@{\tt ShowS} (type synonym)}{121} \indexentry{readsPrec@{\tt readsPrec}}{121} \indexentry{readList@{\tt readList}}{121} \indexentry{Read@{\tt Read} (class)}{121} \indexentry{showsPrec@{\tt showsPrec}}{121} \indexentry{show@{\tt show}}{121} \indexentry{showList@{\tt showList}}{121} \indexentry{Show@{\tt Show} (class)}{121} \indexentry{reads@{\tt reads}}{122} \indexentry{shows@{\tt shows}}{122} \indexentry{read@{\tt read}}{122} \indexentry{showChar@{\tt showChar}}{122} \indexentry{showString@{\tt showString}}{122} \indexentry{showParen@{\tt showParen}}{122} \indexentry{readParen@{\tt readParen}}{122} \indexentry{lex@{\tt lex}}{122} \indexentry{Show@{\tt Show} (class)!instance for {\tt Int}}{123} \indexentry{Read@{\tt Read} (class)!instance for {\tt Int}}{123} \indexentry{Show@{\tt Show} (class)!instance for {\tt Integer}}{123} \indexentry{Read@{\tt Read} (class)!instance for {\tt Integer}}{123} \indexentry{Show@{\tt Show} (class)!instance for {\tt Float}}{123} \indexentry{Read@{\tt Read} (class)!instance for {\tt Float}}{123} \indexentry{Show@{\tt Show} (class)!instance for {\tt Double}}{123} \indexentry{Read@{\tt Read} (class)!instance for {\tt Double}}{123} \indexentry{Show@{\tt Show} (class)!instance for {\tt Char}}{124} \indexentry{Read@{\tt Read} (class)!instance for {\tt Char}}{124} \indexentry{Show@{\tt Show} (class)!instance for {\tt [a]}}{124} \indexentry{Read@{\tt Read} (class)!instance for {\tt [a]}}{124} \indexentry{PreludeIO@{\tt PreludeIO} (module)}{125} \indexentry{PreludeBuiltin@{\tt PreludeBuiltin} (module)}{125} \indexentry{FilePath@{\tt FilePath} (type synonym)}{125} \indexentry{IOError@{\tt IOError} (datatype)}{125} \indexentry{ioError@{\tt ioError}}{125} \indexentry{userError@{\tt userError}}{125} \indexentry{catch@{\tt catch}}{125} \indexentry{putChar@{\tt putChar}}{125} \indexentry{putStr@{\tt putStr}}{125} \indexentry{putStrLn@{\tt putStrLn}}{125} \indexentry{print@{\tt print}}{125} \indexentry{getChar@{\tt getChar}}{125} \indexentry{getLine@{\tt getLine}}{125} \indexentry{getContents@{\tt getContents}}{125} \indexentry{interact@{\tt interact}}{126} \indexentry{readFile@{\tt readFile}}{126} \indexentry{writeFile@{\tt writeFile}}{126} \indexentry{appendFile@{\tt appendFile}}{126} \indexentry{readIO@{\tt readIO}}{126} \indexentry{readLn@{\tt readLn}}{126} \indexentry{syntax}{127} \indexentry{maximal munch rule}{127} \indexentry{program@{\it program}}{129} \indexentry{lexeme@{\it lexeme}}{129} \indexentry{literal@{\it literal}}{129} \indexentry{special@{\it special}}{129} \indexentry{whitespace@{\it whitespace}}{129} \indexentry{whitestuff@{\it whitestuff}}{129} \indexentry{whitechar@{\it whitechar}}{129} \indexentry{uniWhite@{\it uniWhite}}{129} \indexentry{newline@{\it newline}}{129} \indexentry{space@{\it space}}{129} \indexentry{tab@{\it tab}}{129} \indexentry{vertab@{\it vertab}}{129} \indexentry{formfeed@{\it formfeed}}{129} \indexentry{comment@{\it comment}}{129} \indexentry{dashes@{\it dashes}}{129} \indexentry{ncomment@{\it ncomment}}{129} \indexentry{opencom@{\it opencom}}{129} \indexentry{closecom@{\it closecom}}{129} \indexentry{ANYseq@{\it ANYseq}}{129} \indexentry{ANY@{\it ANY}}{129} \indexentry{any@{\it any}}{129} \indexentry{graphic@{\it graphic}}{129} \indexentry{small@{\it small}}{129} \indexentry{ascSmall@{\it ascSmall}}{129} \indexentry{uniSmall@{\it uniSmall}}{129} \indexentry{uniDigit@{\it uniDigit}}{129} \indexentry{large@{\it large}}{129} \indexentry{ascLarge@{\it ascLarge}}{129} \indexentry{uniLarge@{\it uniLarge}}{129} \indexentry{symbol@{\it symbol}}{129} \indexentry{ascSymbol@{\it ascSymbol}}{129} \indexentry{uniSymbol@{\it uniSymbol}}{129} \indexentry{digit@{\it digit}}{129} \indexentry{ascDigit@{\it ascDigit}}{129} \indexentry{uniDigit@{\it uniDigit}}{129} \indexentry{octit@{\it octit}}{129} \indexentry{hexit@{\it hexit}}{129} \indexentry{varid@{\it varid}}{130} \indexentry{conid@{\it conid}}{130} \indexentry{reservedid@{\it reservedid}}{130} \indexentry{varsym@{\it varsym}}{130} \indexentry{consym@{\it consym}}{130} \indexentry{symbol@{\it symbol}}{130} \indexentry{reservedop@{\it reservedop}}{130} \indexentry{tyvar@{\it tyvar}}{130} \indexentry{tycon@{\it tycon}}{130} \indexentry{tycls@{\it tycls}}{130} \indexentry{modid@{\it modid}}{130} \indexentry{qvarid@{\it qvarid}}{130} \indexentry{qconid@{\it qconid}}{130} \indexentry{qtycon@{\it qtycon}}{130} \indexentry{qtycls@{\it qtycls}}{130} \indexentry{qvarsym@{\it qvarsym}}{130} \indexentry{qconsym@{\it qconsym}}{130} \indexentry{decimal@{\it decimal}}{130} \indexentry{octal@{\it octal}}{130} \indexentry{hexadecimal@{\it hexadecimal}}{130} \indexentry{char@{\it char}}{130} \indexentry{string@{\it string}}{130} \indexentry{escape@{\it escape}}{130} \indexentry{charesc@{\it charesc}}{130} \indexentry{ascii@{\it ascii}}{130} \indexentry{cntrl@{\it cntrl}}{130} \indexentry{gap@{\it gap}}{130} \indexentry{layout}{130} \indexentry{literate comments}{134} \indexentry{module@{\it module}}{136} \indexentry{body@{\it body}}{136} \indexentry{modid@{\it modid}}{136} \indexentry{impdecls@{\it impdecls}}{136} \indexentry{exports@{\it exports}}{136} \indexentry{export@{\it export}}{136} \indexentry{impdecl@{\it impdecl}}{136} \indexentry{impspec@{\it impspec}}{136} \indexentry{import@{\it import}}{136} \indexentry{cname@{\it cname}}{136} \indexentry{topdecls@{\it topdecls}}{136} \indexentry{topdecl@{\it topdecl}}{136} \indexentry{vars@{\it vars}}{137} \indexentry{fixity@{\it fixity}}{137} \indexentry{ops@{\it ops}}{137} \indexentry{gendecl@{\it gendecl}}{137} \indexentry{decls@{\it decls}}{137} \indexentry{decl@{\it decl}}{137} \indexentry{cdecls@{\it cdecls}}{137} \indexentry{cdecl@{\it cdecl}}{137} \indexentry{idecls@{\it idecls}}{137} \indexentry{idecl@{\it idecl}}{137} \indexentry{type@{\it type}}{137} \indexentry{btype@{\it btype}}{137} \indexentry{atype@{\it atype}}{137} \indexentry{gtycon@{\it gtycon}}{137} \indexentry{context@{\it context}}{137} \indexentry{class@{\it class}}{137} \indexentry{simpleclass@{\it simpleclass}}{137} \indexentry{scontext@{\it scontext}}{137} \indexentry{simpletype@{\it simpletype}}{138} \indexentry{constrs@{\it constrs}}{138} \indexentry{constr@{\it constr}}{138} \indexentry{fielddecl@{\it fielddecl}}{138} \indexentry{deriving@{\it deriving}}{138} \indexentry{dclass@{\it dclass}}{138} \indexentry{newconstr@{\it newconstr}}{138} \indexentry{inst@{\it inst}}{138} \indexentry{funlhs@{\it funlhs}}{138} \indexentry{rhs@{\it rhs}}{138} \indexentry{gdrhs@{\it gdrhs}}{138} \indexentry{gd@{\it gd}}{138} \indexentry{exp@{\it exp}}{139} \indexentry{exp@\mbox{$\it exp^i$}}{139} \indexentry{lexp@\mbox{$\it lexp^i$}}{139} \indexentry{rexp@\mbox{$\it rexp^i$}}{139} \indexentry{fexp@{\it fexp}}{139} \indexentry{aexp@{\it aexp}}{139} \indexentry{qual@{\it qual}}{139} \indexentry{alts@{\it alts}}{139} \indexentry{alt@{\it alt}}{139} \indexentry{gdpat@{\it gdpat}}{139} \indexentry{stmt@{\it stmt}}{139} \indexentry{stmts@{\it stmts}}{139} \indexentry{fbind@{\it fbind}}{139} \indexentry{pat@{\it pat}}{140} \indexentry{pat@\mbox{$\it pat^i$}}{140} \indexentry{lpat@\mbox{$\it lpat^i$}}{140} \indexentry{rpat@\mbox{$\it rpat^i$}}{140} \indexentry{fpat@{\it fpat}}{140} \indexentry{fpats@{\it fpats}}{140} \indexentry{apat@{\it apat}}{140} \indexentry{gcon@{\it gcon}}{140} \indexentry{var@{\it var}}{140} \indexentry{qvar@{\it qvar}}{140} \indexentry{con@{\it con}}{140} \indexentry{qcon@{\it qcon}}{140} \indexentry{varop@{\it varop}}{140} \indexentry{qvarop@{\it qvarop}}{140} \indexentry{conop@{\it conop}}{140} \indexentry{qconop@{\it qconop}}{140} \indexentry{op@{\it op}}{140} \indexentry{qop@{\it qop}}{140} \indexentry{derived instance}{141} \indexentry{algebraic datatype}{141} \indexentry{Eq@{\tt Eq} (class)!derived instance}{142} \indexentry{Ord@{\tt Ord} (class)!derived instance}{142} \indexentry{==@{\tt ==}}{142} \indexentry{/=@{\tt /=}}{142} \indexentry{compare@{\tt compare}}{142} \indexentry{<@{\tt <}}{142} \indexentry{<=@{\tt <=}}{142} \indexentry{>@{\tt >}}{142} \indexentry{>=@{\tt >=}}{142} \indexentry{max@{\tt max}}{142} \indexentry{min@{\tt min}}{142} \indexentry{Enum@{\tt Enum} (class)!derived instance}{142} \indexentry{Bounded@{\tt Bounded} (class)!derived instance}{143} \indexentry{maxBound@{\tt maxBound}}{143} \indexentry{minBound@{\tt minBound}}{143} \indexentry{Read@{\tt Read} (class)!derived instance}{143} \indexentry{Show@{\tt Show} (class)!derived instance}{143} \indexentry{showsPrec@{\tt showsPrec}}{143} \indexentry{readsPrec@{\tt readsPrec}}{143} \indexentry{showList@{\tt showList}}{143} \indexentry{readList@{\tt readList}}{143} \indexentry{default class method}{145} \indexentry{pragmas}{147} \indexentry{inlining}{147} \indexentry{rational numbers}{151} \indexentry{Ratio@{\tt Ratio} (module)}{151} \indexentry{%@{\tt {\char'045}}}{151} \indexentry{numerator@{\tt numerator}}{151} \indexentry{denominator@{\tt denominator}}{151} \indexentry{approxRational@{\tt approxRational}}{151} \indexentry{%@{\tt {\char'045}}}{151} \indexentry{Rational@{\tt Rational} (type synonym)}{151} \indexentry{Ratio@{\tt Ratio} (datatype)}{151} \indexentry{Rational@{\tt Rational} (type synonym)}{151} \indexentry{%@{\tt {\char'045}}}{151} \indexentry{numerator@{\tt numerator}}{151} \indexentry{denominator@{\tt denominator}}{151} \indexentry{Ratio@{\tt Ratio} (module)}{153} \indexentry{%@{\tt {\char'045}}}{153} \indexentry{Rational@{\tt Rational} (type synonym)}{153} \indexentry{%@{\tt {\char'045}}}{153} \indexentry{numerator@{\tt numerator}}{153} \indexentry{denominator@{\tt denominator}}{153} \indexentry{approxRational@{\tt approxRational}}{153} \indexentry{Ord@{\tt Ord} (class)!instance for {\tt Ratio}}{153} \indexentry{Num@{\tt Num} (class)!instance for {\tt Ratio}}{153} \indexentry{Real@{\tt Real} (class)!instance for {\tt Ratio}}{153} \indexentry{Fractional@{\tt Fractional} (class)!instance for {\tt Ratio}}{153} \indexentry{RealFrac@{\tt RealFrac} (class)!instance for {\tt Ratio}}{154} \indexentry{Enum@{\tt Enum} (class)!instance for {\tt Ratio}}{154} \indexentry{Read@{\tt Read} (class)!instance for {\tt Ratio}}{154} \indexentry{Show@{\tt Show} (class)!instance for {\tt Ratio}}{154} \indexentry{Complex@{\tt Complex} (module)}{155} \indexentry{:+@{\tt :+}}{155} \indexentry{realPart@{\tt realPart}}{155} \indexentry{imagPart@{\tt imagPart}}{155} \indexentry{conjugate@{\tt conjugate}}{155} \indexentry{mkPolar@{\tt mkPolar}}{155} \indexentry{cis@{\tt cis}}{155} \indexentry{polar@{\tt polar}}{155} \indexentry{magnitude@{\tt magnitude}}{155} \indexentry{phase@{\tt phase}}{155} \indexentry{:+@{\tt :+}}{155} \indexentry{mkPolar@{\tt mkPolar}}{155} \indexentry{polar@{\tt polar}}{155} \indexentry{polar@{\tt polar}}{155} \indexentry{realPart@{\tt realPart}}{156} \indexentry{imagPart@{\tt imagPart}}{156} \indexentry{magnitude@{\tt magnitude}}{156} \indexentry{phase@{\tt phase}}{156} \indexentry{conjugate@{\tt conjugate}}{156} \indexentry{Complex@{\tt Complex} (module)}{156} \indexentry{:+@{\tt :+}}{156} \indexentry{realPart@{\tt realPart}}{156} \indexentry{imagPart@{\tt imagPart}}{156} \indexentry{conjugate@{\tt conjugate}}{156} \indexentry{mkPolar@{\tt mkPolar}}{156} \indexentry{cis@{\tt cis}}{156} \indexentry{polar@{\tt polar}}{156} \indexentry{magnitude@{\tt magnitude}}{156} \indexentry{phase@{\tt phase}}{156} \indexentry{Num@{\tt Num} (class)!instance for {\tt Complex}}{157} \indexentry{Fractional@{\tt Fractional} (class)!instance for {\tt Complex}}{157} \indexentry{Floating@{\tt Floating} (class)!instance for {\tt Complex}}{158} \indexentry{Numeric@{\tt Numeric} (module)}{159} \indexentry{fromRat@{\tt fromRat}}{159} \indexentry{showSigned@{\tt showSigned}}{159} \indexentry{showIntAtBase@{\tt showIntAtBase}}{159} \indexentry{showInt@{\tt showInt}}{159} \indexentry{showOct@{\tt showOct}}{159} \indexentry{showHex@{\tt showHex}}{159} \indexentry{readSigned@{\tt readSigned}}{159} \indexentry{readInt@{\tt readInt}}{159} \indexentry{readDec@{\tt readDec}}{159} \indexentry{readOct@{\tt readOct}}{159} \indexentry{readHex@{\tt readHex}}{159} \indexentry{showEFloat@{\tt showEFloat}}{159} \indexentry{showFFloat@{\tt showFFloat}}{159} \indexentry{showGFloat@{\tt showGFloat}}{159} \indexentry{showFloat@{\tt showFloat}}{159} \indexentry{floatToDigits@{\tt floatToDigits}}{159} \indexentry{readFloat@{\tt readFloat}}{159} \indexentry{lexDigits@{\tt lexDigits}}{159} \indexentry{Numeric@{\tt Numeric} (module)}{161} \indexentry{Char@{\tt Char} (module)}{161} \indexentry{Ratio@{\tt Ratio} (module)}{161} \indexentry{Array@{\tt Array} (module)}{161} \indexentry{fromRat@{\tt fromRat}}{162} \indexentry{fromRat'@{\tt fromRat'}}{162} \indexentry{scaleRat@{\tt scaleRat}}{162} \indexentry{expt@{\tt expt}}{162} \indexentry{expts@{\tt expts}}{163} \indexentry{integerLogBase@{\tt integerLogBase}}{163} \indexentry{doDiv@{\tt doDiv}}{163} \indexentry{showSigned@{\tt showSigned}}{163} \indexentry{showInt@{\tt showInt}}{163} \indexentry{showOct@{\tt showOct}}{163} \indexentry{showHex@{\tt showHex}}{163} \indexentry{showIntAtBase@{\tt showIntAtBase}}{163} \indexentry{readSigned@{\tt readSigned}}{163} \indexentry{readInt@{\tt readInt}}{164} \indexentry{readDec@{\tt readDec}}{164} \indexentry{readOct@{\tt readOct}}{164} \indexentry{readHex@{\tt readHex}}{164} \indexentry{showEFloat@{\tt showEFloat}}{164} \indexentry{showFFloat@{\tt showFFloat}}{164} \indexentry{showGFloat@{\tt showGFloat}}{164} \indexentry{showFloat@{\tt showFloat}}{164} \indexentry{FFFormat@{\tt FFFormat} (datatype)}{164} \indexentry{formatRealFloat@{\tt formatRealFloat}}{165} \indexentry{roundTo@{\tt roundTo}}{166} \indexentry{floatToDigits@{\tt floatToDigits}}{166} \indexentry{f@{\tt f}}{167} \indexentry{e@{\tt e}}{167} \indexentry{readFloat@{\tt readFloat}}{168} \indexentry{lexDigits@{\tt lexDigits}}{168} \indexentry{nonnull@{\tt nonnull}}{168} \indexentry{Ix@{\tt Ix} (module)}{169} \indexentry{range@{\tt range}}{169} \indexentry{index@{\tt index}}{169} \indexentry{inRange@{\tt inRange}}{169} \indexentry{rangeSize@{\tt rangeSize}}{169} \indexentry{Ix@{\tt Ix} (class)}{169} \indexentry{range@{\tt range}}{169} \indexentry{index@{\tt index}}{169} \indexentry{inRange@{\tt inRange}}{169} \indexentry{Ix@{\tt Ix} (class)!derived instance}{170} \indexentry{enumeration}{170} \indexentry{Ix@{\tt Ix} (class)}{171} \indexentry{range@{\tt range}}{171} \indexentry{index@{\tt index}}{171} \indexentry{inRange@{\tt inRange}}{171} \indexentry{rangeSize@{\tt rangeSize}}{171} \indexentry{Ix@{\tt Ix} (module)}{172} \indexentry{range@{\tt range}}{172} \indexentry{index@{\tt index}}{172} \indexentry{inRange@{\tt inRange}}{172} \indexentry{rangeSize@{\tt rangeSize}}{172} \indexentry{Ix@{\tt Ix} (class)}{172} \indexentry{Ix@{\tt Ix} (class)!instance for {\tt Char}}{172} \indexentry{Ix@{\tt Ix} (class)!instance for {\tt Int}}{172} \indexentry{Ix@{\tt Ix} (class)!instance for {\tt Integer}}{172} \indexentry{array}{173} \indexentry{Array@{\tt Array} (module)}{173} \indexentry{Ix@{\tt Ix} (module)}{173} \indexentry{Ix@{\tt Ix} (module)}{173} \indexentry{"!@{\tt {\char'041}}}{173} \indexentry{//@{\tt //}}{173} \indexentry{array@{\tt array}}{173} \indexentry{listArray@{\tt listArray}}{173} \indexentry{"!@{\tt {\char'041}}}{173} \indexentry{bounds@{\tt bounds}}{173} \indexentry{indices@{\tt indices}}{173} \indexentry{elems@{\tt elems}}{173} \indexentry{assocs@{\tt assocs}}{173} \indexentry{accumArray@{\tt accumArray}}{173} \indexentry{//@{\tt //}}{173} \indexentry{accum@{\tt accum}}{173} \indexentry{ixmap@{\tt ixmap}}{173} \indexentry{Array@{\tt Array} (datatype)}{174} \indexentry{array@{\tt array}}{174} \indexentry{"!@{\tt {\char'041}}}{174} \indexentry{bounds@{\tt bounds}}{174} \indexentry{indices@{\tt indices}}{174} \indexentry{elems@{\tt elems}}{174} \indexentry{assocs@{\tt assocs}}{174} \indexentry{listArray@{\tt listArray}}{174} \indexentry{array!accumulated}{174} \indexentry{accumArray@{\tt accumArray}}{174} \indexentry{//@{\tt //}}{175} \indexentry{accum@{\tt accum}}{175} \indexentry{array!derived}{176} \indexentry{fmap@{\tt fmap}}{176} \indexentry{ixmap@{\tt ixmap}}{176} \indexentry{Array@{\tt Array} (module)}{176} \indexentry{Ix@{\tt Ix} (module)}{176} \indexentry{Ix@{\tt Ix} (module)}{176} \indexentry{List@{\tt List} (module)}{176} \indexentry{"!@{\tt {\char'041}}}{176} \indexentry{//@{\tt //}}{176} \indexentry{array@{\tt array}}{177} \indexentry{listArray@{\tt listArray}}{177} \indexentry{"!@{\tt {\char'041}}}{177} \indexentry{bounds@{\tt bounds}}{177} \indexentry{indices@{\tt indices}}{177} \indexentry{elems@{\tt elems}}{177} \indexentry{assocs@{\tt assocs}}{177} \indexentry{//@{\tt //}}{177} \indexentry{accum@{\tt accum}}{177} \indexentry{accumArray@{\tt accumArray}}{177} \indexentry{ixmap@{\tt ixmap}}{177} \indexentry{Functor@{\tt Functor} (class)!instance for {\tt Array}}{177} \indexentry{Eq@{\tt Eq} (class)!instance for {\tt Array}}{177} \indexentry{Ord@{\tt Ord} (class)!instance for {\tt Array}}{178} \indexentry{Show@{\tt Show} (class)!instance for {\tt Array}}{178} \indexentry{Read@{\tt Read} (class)!instance for {\tt Array}}{178} \indexentry{List@{\tt List} (module)}{180} \indexentry{\\@{\tt {\char'134}{\char'134}}}{180} \indexentry{elemIndex@{\tt elemIndex}}{180} \indexentry{elemIndices@{\tt elemIndices}}{180} \indexentry{find@{\tt find}}{180} \indexentry{findIndex@{\tt findIndex}}{180} \indexentry{findIndices@{\tt findIndices}}{180} \indexentry{nub@{\tt nub}}{180} \indexentry{nubBy@{\tt nubBy}}{180} \indexentry{delete@{\tt delete}}{180} \indexentry{deleteBy@{\tt deleteBy}}{180} \indexentry{\\@{\tt {\char'134}{\char'134}}}{180} \indexentry{deleteFirstsBy@{\tt deleteFirstsBy}}{180} \indexentry{union@{\tt union}}{180} \indexentry{unionBy@{\tt unionBy}}{180} \indexentry{intersect@{\tt intersect}}{181} \indexentry{intersectBy@{\tt intersectBy}}{181} \indexentry{intersperse@{\tt intersperse}}{181} \indexentry{transpose@{\tt transpose}}{181} \indexentry{partition@{\tt partition}}{181} \indexentry{group@{\tt group}}{181} \indexentry{groupBy@{\tt groupBy}}{181} \indexentry{inits@{\tt inits}}{181} \indexentry{tails@{\tt tails}}{181} \indexentry{isPrefixOf@{\tt isPrefixOf}}{181} \indexentry{isSuffixOf@{\tt isSuffixOf}}{181} \indexentry{mapAccumL@{\tt mapAccumL}}{181} \indexentry{mapAccumR@{\tt mapAccumR}}{181} \indexentry{unfoldr@{\tt unfoldr}}{181} \indexentry{sort@{\tt sort}}{181} \indexentry{sortBy@{\tt sortBy}}{181} \indexentry{insert@{\tt insert}}{181} \indexentry{insertBy@{\tt insertBy}}{181} \indexentry{maximumBy@{\tt maximumBy}}{181} \indexentry{minimumBy@{\tt minimumBy}}{181} \indexentry{genericLength@{\tt genericLength}}{181} \indexentry{genericTake@{\tt genericTake}}{181} \indexentry{genericDrop@{\tt genericDrop}}{181} \indexentry{genericSplitAt@{\tt genericSplitAt}}{181} \indexentry{genericIndex@{\tt genericIndex}}{181} \indexentry{genericReplicate@{\tt genericReplicate}}{181} \indexentry{zip4@{\tt zip4}}{181} \indexentry{zip5@{\tt zip5}}{181} \indexentry{zip6@{\tt zip6}}{181} \indexentry{zip7@{\tt zip7}}{181} \indexentry{zipWith4@{\tt zipWith4}}{181} \indexentry{zipWith5@{\tt zipWith5}}{181} \indexentry{zipWith6@{\tt zipWith6}}{181} \indexentry{zipWith7@{\tt zipWith7}}{181} \indexentry{unzip4@{\tt unzip4}}{181} \indexentry{unzip5@{\tt unzip5}}{181} \indexentry{unzip6@{\tt unzip6}}{181} \indexentry{unzip7@{\tt unzip7}}{181} \indexentry{elemIndex@{\tt elemIndex}}{182} \indexentry{elemIndices@{\tt elemIndices}}{182} \indexentry{find@{\tt find}}{182} \indexentry{nub@{\tt nub}}{182} \indexentry{delete@{\tt delete}}{182} \indexentry{\\\\@{\tt {\char'134}{\char'134}}}{182} \indexentry{union@{\tt union}}{182} \indexentry{intersect@{\tt intersect}}{182} \indexentry{intersperse@{\tt intersperse}}{183} \indexentry{transpose@{\tt transpose}}{183} \indexentry{partition@{\tt partition}}{183} \indexentry{sort@{\tt sort}}{183} \indexentry{insert@{\tt insert}}{183} \indexentry{group@{\tt group}}{183} \indexentry{inits@{\tt inits}}{183} \indexentry{tails@{\tt tails}}{183} \indexentry{mapAccumL@{\tt mapAccumL}}{183} \indexentry{mapAccumR@{\tt mapAccumR}}{183} \indexentry{nubBy@{\tt nubBy}}{184} \indexentry{deleteBy@{\tt deleteBy}}{184} \indexentry{deleteFirstsBy@{\tt deleteFirstsBy}}{184} \indexentry{unionBy@{\tt unionBy}}{184} \indexentry{intersectBy@{\tt intersectBy}}{184} \indexentry{groupBy@{\tt groupBy}}{184} \indexentry{sortBy@{\tt sortBy}}{184} \indexentry{insertBy@{\tt insertBy}}{184} \indexentry{maximumBy@{\tt maximumBy}}{184} \indexentry{minimumBy@{\tt minimumBy}}{184} \indexentry{zip4@{\tt zip4}}{185} \indexentry{unzip4@{\tt unzip4}}{185} \indexentry{zipWith4@{\tt zipWith4}}{185} \indexentry{List@{\tt List} (module)}{186} \indexentry{Maybe@{\tt Maybe} (module)}{186} \indexentry{\\@{\tt {\char'134}{\char'134}}}{186} \indexentry{elemIndex@{\tt elemIndex}}{186} \indexentry{elemIndices@{\tt elemIndices}}{186} \indexentry{find@{\tt find}}{186} \indexentry{findIndex@{\tt findIndex}}{186} \indexentry{findIndices@{\tt findIndices}}{186} \indexentry{nub@{\tt nub}}{186} \indexentry{nubBy@{\tt nubBy}}{187} \indexentry{delete@{\tt delete}}{187} \indexentry{deleteBy@{\tt deleteBy}}{187} \indexentry{\\@{\tt {\char'134}{\char'134}}}{187} \indexentry{deleteFirstsBy@{\tt deleteFirstsBy}}{187} \indexentry{union@{\tt union}}{187} \indexentry{unionBy@{\tt unionBy}}{187} \indexentry{intersect@{\tt intersect}}{187} \indexentry{intersectBy@{\tt intersectBy}}{187} \indexentry{intersperse@{\tt intersperse}}{187} \indexentry{transpose@{\tt transpose}}{187} \indexentry{partition@{\tt partition}}{187} \indexentry{group@{\tt group}}{187} \indexentry{groupBy@{\tt groupBy}}{188} \indexentry{inits@{\tt inits}}{188} \indexentry{tails@{\tt tails}}{188} \indexentry{isPrefixOf@{\tt isPrefixOf}}{188} \indexentry{isSuffixOf@{\tt isSuffixOf}}{188} \indexentry{mapAccumL@{\tt mapAccumL}}{188} \indexentry{mapAccumR@{\tt mapAccumR}}{188} \indexentry{unfoldr@{\tt unfoldr}}{188} \indexentry{sort@{\tt sort}}{188} \indexentry{sortBy@{\tt sortBy}}{188} \indexentry{insert@{\tt insert}}{188} \indexentry{insertBy@{\tt insertBy}}{189} \indexentry{maximumBy@{\tt maximumBy}}{189} \indexentry{minimumBy@{\tt minimumBy}}{189} \indexentry{genericLength@{\tt genericLength}}{189} \indexentry{genericTake@{\tt genericTake}}{189} \indexentry{genericDrop@{\tt genericDrop}}{189} \indexentry{genericSplitAt@{\tt genericSplitAt}}{189} \indexentry{genericIndex@{\tt genericIndex}}{190} \indexentry{genericReplicate@{\tt genericReplicate}}{190} \indexentry{zip4@{\tt zip4}}{190} \indexentry{zip5@{\tt zip5}}{190} \indexentry{zip6@{\tt zip6}}{190} \indexentry{zip7@{\tt zip7}}{190} \indexentry{zipWith4@{\tt zipWith4}}{190} \indexentry{zipWith5@{\tt zipWith5}}{190} \indexentry{zipWith6@{\tt zipWith6}}{190} \indexentry{zipWith7@{\tt zipWith7}}{190} \indexentry{unzip4@{\tt unzip4}}{190} \indexentry{unzip5@{\tt unzip5}}{191} \indexentry{unzip6@{\tt unzip6}}{191} \indexentry{unzip7@{\tt unzip7}}{191} \indexentry{Maybe@{\tt Maybe} (module)}{193} \indexentry{isJust@{\tt isJust}}{193} \indexentry{isNothing@{\tt isNothing}}{193} \indexentry{fromJust@{\tt fromJust}}{193} \indexentry{fromMaybe@{\tt fromMaybe}}{193} \indexentry{listToMaybe@{\tt listToMaybe}}{193} \indexentry{maybeToList@{\tt maybeToList}}{193} \indexentry{catMaybes@{\tt catMaybes}}{193} \indexentry{mapMaybe@{\tt mapMaybe}}{193} \indexentry{Maybe@{\tt Maybe} (module)}{194} \indexentry{isJust@{\tt isJust}}{194} \indexentry{isNothing@{\tt isNothing}}{194} \indexentry{fromJust@{\tt fromJust}}{194} \indexentry{fromMaybe@{\tt fromMaybe}}{194} \indexentry{maybeToList@{\tt maybeToList}}{194} \indexentry{listToMaybe@{\tt listToMaybe}}{194} \indexentry{catMaybes@{\tt catMaybes}}{194} \indexentry{mapMaybe@{\tt mapMaybe}}{194} \indexentry{Char@{\tt Char} (module)}{195} \indexentry{isAscii@{\tt isAscii}}{195} \indexentry{isLatin1@{\tt isLatin1}}{195} \indexentry{isControl@{\tt isControl}}{195} \indexentry{isPrint@{\tt isPrint}}{195} \indexentry{isSpace@{\tt isSpace}}{195} \indexentry{isUpper@{\tt isUpper}}{195} \indexentry{isLower@{\tt isLower}}{195} \indexentry{isAlpha@{\tt isAlpha}}{195} \indexentry{isDigit@{\tt isDigit}}{195} \indexentry{isOctDigit@{\tt isOctDigit}}{195} \indexentry{isHexDigit@{\tt isHexDigit}}{195} \indexentry{isAlphaNum@{\tt isAlphaNum}}{195} \indexentry{toUpper@{\tt toUpper}}{195} \indexentry{toLower@{\tt toLower}}{195} \indexentry{digitToInt@{\tt digitToInt}}{195} \indexentry{intToDigit@{\tt intToDigit}}{195} \indexentry{ord@{\tt ord}}{195} \indexentry{chr@{\tt chr}}{195} \indexentry{lexLitChar@{\tt lexLitChar}}{195} \indexentry{readLitChar@{\tt readLitChar}}{195} \indexentry{showLitChar@{\tt showLitChar}}{195} \indexentry{isAscii@{\tt isAscii}}{195} \indexentry{isLatin1@{\tt isLatin1}}{195} \indexentry{isControl@{\tt isControl}}{195} \indexentry{isPrint@{\tt isPrint}}{195} \indexentry{isSpace@{\tt isSpace}}{195} \indexentry{isUpper@{\tt isUpper}}{195} \indexentry{isLower@{\tt isLower}}{195} \indexentry{isAlpha@{\tt isAlpha}}{195} \indexentry{isDigit@{\tt isDigit}}{195} \indexentry{isOctDigit@{\tt isOctDigit}}{195} \indexentry{isHexDigit@{\tt isHexDigit}}{195} \indexentry{isAlphaNum@{\tt isAlphaNum}}{195} \indexentry{toUpper@{\tt toUpper}}{195} \indexentry{toLower@{\tt toLower}}{195} \indexentry{Char@{\tt Char} (module)}{197} \indexentry{Array@{\tt Array} (module)}{197} \indexentry{Numeric@{\tt Numeric} (module)}{197} \indexentry{UnicodePrims@{\tt UnicodePrims} (module)}{197} \indexentry{isAscii@{\tt isAscii}}{197} \indexentry{isLatin1@{\tt isLatin1}}{197} \indexentry{isControl@{\tt isControl}}{197} \indexentry{isPrint@{\tt isPrint}}{197} \indexentry{isSpace@{\tt isSpace}}{197} \indexentry{isUpper@{\tt isUpper}}{197} \indexentry{isLower@{\tt isLower}}{197} \indexentry{isAlpha@{\tt isAlpha}}{197} \indexentry{isDigit@{\tt isDigit}}{197} \indexentry{isOctDigit@{\tt isOctDigit}}{197} \indexentry{isHexDigit@{\tt isHexDigit}}{197} \indexentry{isAlphaNum@{\tt isAlphaNum}}{197} \indexentry{digitToInt@{\tt digitToInt}}{197} \indexentry{intToDigit@{\tt intToDigit}}{198} \indexentry{toUpper@{\tt toUpper}}{198} \indexentry{toLower@{\tt toLower}}{198} \indexentry{ord@{\tt ord}}{198} \indexentry{chr@{\tt chr}}{198} \indexentry{readLitChar@{\tt readLitChar}}{198} \indexentry{readEsc@{\tt readEsc}}{198} \indexentry{match@{\tt match}}{198} \indexentry{showLitChar@{\tt showLitChar}}{199} \indexentry{lexLitChar@{\tt lexLitChar}}{199} \indexentry{Monad@{\tt Monad} (module)}{202} \indexentry{mzero@{\tt mzero}}{202} \indexentry{mplus@{\tt mplus}}{202} \indexentry{MonadPlus@{\tt MonadPlus} (class)}{202} \indexentry{join@{\tt join}}{202} \indexentry{guard@{\tt guard}}{202} \indexentry{when@{\tt when}}{202} \indexentry{unless@{\tt unless}}{202} \indexentry{ap@{\tt ap}}{202} \indexentry{mapAndUnzipM@{\tt mapAndUnzipM}}{202} \indexentry{zipWithM@{\tt zipWithM}}{202} \indexentry{zipWithM{\char '137}@{\tt zipWithM{\char '137}}}{202} \indexentry{foldM@{\tt foldM}}{202} \indexentry{filterM@{\tt filterM}}{202} \indexentry{msum@{\tt msum}}{202} \indexentry{liftM@{\tt liftM}}{202} \indexentry{liftM2@{\tt liftM2}}{202} \indexentry{liftM3@{\tt liftM3}}{202} \indexentry{liftM4@{\tt liftM4}}{202} \indexentry{liftM5@{\tt liftM5}}{202} \indexentry{Monad@{\tt Monad} (module)}{206} \indexentry{mzero@{\tt mzero}}{206} \indexentry{mplus@{\tt mplus}}{206} \indexentry{MonadPlus@{\tt MonadPlus} (class)}{206} \indexentry{Monad@{\tt Monad} (class)!superclass of {\tt MonadPlus}}{206} \indexentry{MonadPlus@{\tt MonadPlus} (class)!instance for {\tt Maybe}}{206} \indexentry{MonadPlus@{\tt MonadPlus} (class)!instance for {\tt []}}{206} \indexentry{msum@{\tt msum}}{206} \indexentry{join@{\tt join}}{206} \indexentry{when@{\tt when}}{206} \indexentry{unless@{\tt unless}}{206} \indexentry{ap@{\tt ap}}{206} \indexentry{guard@{\tt guard}}{206} \indexentry{mapAndUnzipM@{\tt mapAndUnzipM}}{206} \indexentry{zipWithM@{\tt zipWithM}}{207} \indexentry{zipWithM{\char '137}@{\tt zipWithM{\char '137}}}{207} \indexentry{foldM@{\tt foldM}}{207} \indexentry{filterM@{\tt filterM}}{207} \indexentry{liftM@{\tt liftM}}{207} \indexentry{liftM2@{\tt liftM2}}{207} \indexentry{liftM3@{\tt liftM3}}{207} \indexentry{liftM4@{\tt liftM4}}{207} \indexentry{liftM5@{\tt liftM5}}{207} \indexentry{input/output}{210} \indexentry{I/O}{210} \indexentry{IO@{\tt IO}}{210} \indexentry{IO@{\tt IO} (module)}{210} \indexentry{Ix@{\tt Ix} (module)}{210} \indexentry{Handle@{\tt Handle} (datatype)}{210} \indexentry{Show@{\tt Show} (class)!instance for {\tt HandlePosn}}{210} \indexentry{Show@{\tt Show} (class)!instance for {\tt HandlePosn}}{210} \indexentry{HandlePosn@{\tt HandlePosn} (datatype)}{210} \indexentry{IOMode@{\tt IOMode} (datatype)}{210} \indexentry{BufferMode@{\tt BufferMode} (datatype)}{210} \indexentry{SeekMode@{\tt SeekMode} (datatype)}{210} \indexentry{stdin@{\tt stdin}}{210} \indexentry{stdout@{\tt stdout}}{210} \indexentry{stderr@{\tt stderr}}{210} \indexentry{openFile@{\tt openFile}}{210} \indexentry{hClose@{\tt hClose}}{210} \indexentry{hFileSize@{\tt hFileSize}}{211} \indexentry{hIsEOF@{\tt hIsEOF}}{211} \indexentry{isEOF@{\tt isEOF}}{211} \indexentry{hSetBuffering@{\tt hSetBuffering}}{211} \indexentry{hGetBuffering@{\tt hGetBuffering}}{211} \indexentry{hFlush@{\tt hFlush}}{211} \indexentry{hGetPosn@{\tt hGetPosn}}{211} \indexentry{hSetPosn@{\tt hSetPosn}}{211} \indexentry{hSeek@{\tt hSeek}}{211} \indexentry{hWaitForInput@{\tt hWaitForInput}}{211} \indexentry{hReady@{\tt hReady}}{211} \indexentry{hGetChar@{\tt hGetChar}}{211} \indexentry{hGetLine@{\tt hGetLine}}{211} \indexentry{hLookAhead@{\tt hLookAhead}}{211} \indexentry{hGetContents@{\tt hGetContents}}{211} \indexentry{hPutChar@{\tt hPutChar}}{211} \indexentry{hPutStr@{\tt hPutStr}}{211} \indexentry{hPutStrLn@{\tt hPutStrLn}}{211} \indexentry{hPrint@{\tt hPrint}}{211} \indexentry{hIsOpen@{\tt hIsOpen}}{211} \indexentry{hIsClosed@{\tt hIsClosed}}{211} \indexentry{hIsReadable@{\tt hIsReadable}}{211} \indexentry{hIsWritable@{\tt hIsWritable}}{211} \indexentry{hIsSeekable@{\tt hIsSeekable}}{211} \indexentry{isAlreadyExistsError@{\tt isAlreadyExistsError}}{211} \indexentry{isDoesNotExistError@{\tt isDoesNotExistError}}{211} \indexentry{isAlreadyInUseError@{\tt isAlreadyInUseError}}{211} \indexentry{isFullError@{\tt isFullError}}{211} \indexentry{isEOFError@{\tt isEOFError}}{211} \indexentry{isIllegalOperation@{\tt isIllegalOperation}}{211} \indexentry{isPermissionError@{\tt isPermissionError}}{211} \indexentry{isUserError@{\tt isUserError}}{211} \indexentry{ioeGetErrorString@{\tt ioeGetErrorString}}{211} \indexentry{ioeGetHandle@{\tt ioeGetHandle}}{211} \indexentry{ioeGetFileName@{\tt ioeGetFileName}}{211} \indexentry{try@{\tt try}}{211} \indexentry{bracket@{\tt bracket}}{211} \indexentry{bracket{\char '137}@{\tt bracket{\char '137}}}{211} \indexentry{I/O errors}{212} \indexentry{IOError@{\tt IOError} (datatype)}{212} \indexentry{isAlreadyExistsError@{\tt isAlreadyExistsError}}{212} \indexentry{isDoesNotExistError@{\tt isDoesNotExistError}}{212} \indexentry{isAlreadyInUseError@{\tt isAlreadyInUseError}}{212} \indexentry{isFullError@{\tt isFullError}}{212} \indexentry{isEOFError@{\tt isEOFError}}{212} \indexentry{isIllegalOperation@{\tt isIllegalOperation}}{212} \indexentry{isPermissionError@{\tt isPermissionError}}{212} \indexentry{isUserError@{\tt isUserError}}{212} \indexentry{fail@{\tt fail}}{212} \indexentry{ioeGetHandle@{\tt ioeGetHandle}}{212} \indexentry{ioeGetFileName@{\tt ioeGetFileName}}{212} \indexentry{ioeGetErrorString@{\tt ioeGetErrorString}}{212} \indexentry{file system}{213} \indexentry{directories}{213} \indexentry{file}{213} \indexentry{physical file}{213} \indexentry{handles}{213} \indexentry{standard handles}{213} \indexentry{stdin@{\tt stdin}}{213} \indexentry{stdout@{\tt stdout}}{213} \indexentry{stderr@{\tt stderr}}{213} \indexentry{semi-closed handles}{214} \indexentry{hGetContents@{\tt hGetContents}}{214} \indexentry{readFile@{\tt readFile}}{214} \indexentry{writeFile@{\tt writeFile}}{214} \indexentry{opening a file}{214} \indexentry{creating a file}{214} \indexentry{openFile@{\tt openFile}}{214} \indexentry{IOMode@{\tt IOMode} (datatype)}{214} \indexentry{ReadMode@{\tt ReadMode}}{214} \indexentry{WriteMode@{\tt WriteMode}}{214} \indexentry{AppendMode@{\tt AppendMode}}{214} \indexentry{ReadWriteMode@{\tt ReadWriteMode}}{214} \indexentry{isAlreadyInUseError@{\tt isAlreadyInUseError}}{215} \indexentry{isDoesNotExistError@{\tt isDoesNotExistError}}{215} \indexentry{isPermissionError@{\tt isPermissionError}}{215} \indexentry{closing a file}{215} \indexentry{hClose@{\tt hClose}}{215} \indexentry{size of file}{215} \indexentry{hFileSize@{\tt hFileSize}}{215} \indexentry{end of file}{215} \indexentry{hIsEOF@{\tt hIsEOF}}{215} \indexentry{isEOF@{\tt isEOF}}{215} \indexentry{file buffering}{215} \indexentry{hLookAhead@{\tt hLookAhead}}{216} \indexentry{hSetBuffering@{\tt hSetBuffering}}{216} \indexentry{hGetBuffering@{\tt hGetBuffering}}{217} \indexentry{flushing a file buffer}{217} \indexentry{hFlush@{\tt hFlush}}{217} \indexentry{random access files}{217} \indexentry{seeking a file}{217} \indexentry{hGetPosn@{\tt hGetPosn}}{217} \indexentry{hSetPosn@{\tt hSetPosn}}{217} \indexentry{hSeek@{\tt hSeek}}{217} \indexentry{SeekMode@{\tt SeekMode} (datatype)}{217} \indexentry{AbsoluteSeek@{\tt AbsoluteSeek}}{217} \indexentry{RelativeSeek@{\tt RelativeSeek}}{217} \indexentry{SeekFromEnd@{\tt SeekFromEnd}}{217} \indexentry{hIsOpen@{\tt hIsOpen}}{218} \indexentry{hIsClosed@{\tt hIsClosed}}{218} \indexentry{hIsReadable@{\tt hIsReadable}}{218} \indexentry{hIsWritable@{\tt hIsWritable}}{218} \indexentry{hIsSeekable@{\tt hIsSeekable}}{218} \indexentry{reading from a file}{218} \indexentry{polling a handle for input}{218} \indexentry{hWaitForInput@{\tt hWaitForInput}}{218} \indexentry{hReady@{\tt hReady}}{218} \indexentry{hGetChar@{\tt hGetChar}}{218} \indexentry{hGetLine@{\tt hGetLine}}{218} \indexentry{lookahead}{219} \indexentry{hLookAhead@{\tt hLookAhead}}{219} \indexentry{get the contents of a file}{219} \indexentry{hGetContents@{\tt hGetContents}}{219} \indexentry{hPutChar@{\tt hPutChar}}{219} \indexentry{hPutStr@{\tt hPutStr}}{219} \indexentry{hPrint@{\tt hPrint}}{219} \indexentry{input/output examples}{219} \indexentry{IO@{\tt IO} (module)}{221} \indexentry{try@{\tt try}}{221} \indexentry{bracket@{\tt bracket}}{221} \indexentry{bracket{\char '137}@{\tt bracket{\char '137}}}{221} \indexentry{directories}{224} \indexentry{the file system}{224} \indexentry{Directory@{\tt Directory} (module)}{224} \indexentry{Time@{\tt Time} (module)}{224} \indexentry{readable@{\tt readable}}{224} \indexentry{writable@{\tt writable}}{224} \indexentry{executable@{\tt executable}}{224} \indexentry{searchable@{\tt searchable}}{224} \indexentry{Permissions@{\tt Permissions} (datatype)}{224} \indexentry{createDirectory@{\tt createDirectory}}{224} \indexentry{removeDirectory@{\tt removeDirectory}}{224} \indexentry{removeFile@{\tt removeFile}}{224} \indexentry{renameDirectory@{\tt renameDirectory}}{224} \indexentry{renameFile@{\tt renameFile}}{224} \indexentry{getDirectoryContents@{\tt getDirectoryContents}}{224} \indexentry{getCurrentDirectory@{\tt getCurrentDirectory}}{224} \indexentry{setCurrentDirectory@{\tt setCurrentDirectory}}{224} \indexentry{doesFileExist@{\tt doesFileExist}}{224} \indexentry{doesDirectoryExist@{\tt doesDirectoryExist}}{224} \indexentry{getPermissions@{\tt getPermissions}}{224} \indexentry{setPermissions@{\tt setPermissions}}{224} \indexentry{getModificationTime@{\tt getModificationTime}}{224} \indexentry{createDirectory@{\tt createDirectory}}{225} \indexentry{removeDirectory@{\tt removeDirectory}}{225} \indexentry{removeFile@{\tt removeFile}}{225} \indexentry{renameDirectory@{\tt renameDirectory}}{225} \indexentry{renameFile@{\tt renameFile}}{225} \indexentry{getDirectoryContents@{\tt getDirectoryContents}}{225} \indexentry{getCurrentDirectory@{\tt getCurrentDirectory}}{225} \indexentry{setCurrentDirectory@{\tt setCurrentDirectory}}{225} \indexentry{path}{225} \indexentry{making directories}{225} \indexentry{deleting directories}{225} \indexentry{removing directories}{225} \indexentry{deleting files}{225} \indexentry{removing files}{225} \indexentry{renaming directories}{225} \indexentry{moving directories}{225} \indexentry{renaming files}{225} \indexentry{moving files}{225} \indexentry{reading a directory}{226} \indexentry{current directory}{226} \indexentry{changing the directory}{226} \indexentry{setting the directory}{226} \indexentry{System@{\tt System} (module)}{229} \indexentry{ExitCode@{\tt ExitCode} (datatype)}{229} \indexentry{getArgs@{\tt getArgs}}{229} \indexentry{getProgName@{\tt getProgName}}{229} \indexentry{getEnv@{\tt getEnv}}{229} \indexentry{system@{\tt system}}{229} \indexentry{exitWith@{\tt exitWith}}{229} \indexentry{exitFailure@{\tt exitFailure}}{229} \indexentry{ExitCode@{\tt ExitCode} (datatype)}{229} \indexentry{ExitSuccess@{\tt ExitSuccess}}{229} \indexentry{ExitFailure@{\tt ExitFailure}}{229} \indexentry{getArgs@{\tt getArgs}}{229} \indexentry{getProgName@{\tt getProgName}}{229} \indexentry{getEnv@{\tt getEnv}}{229} \indexentry{system@{\tt system}}{229} \indexentry{exitWith@{\tt exitWith}}{229} \indexentry{exitFailure@{\tt exitFailure}}{229} \indexentry{program arguments}{229} \indexentry{program name}{229} \indexentry{environment variables}{229} \indexentry{operating system commands}{230} \indexentry{terminating a program}{230} \indexentry{error@{\tt error}}{230} \indexentry{\mbox{$\it \bot$}}{230} \indexentry{catch@{\tt catch}}{230} \indexentry{time}{232} \indexentry{time of day}{232} \indexentry{clock time}{232} \indexentry{Time@{\tt Time} (module)}{232} \indexentry{Ix@{\tt Ix} (module)}{232} \indexentry{ClockTime@{\tt ClockTime} (datatype)}{232} \indexentry{Month@{\tt Month} (datatype)}{232} \indexentry{Day@{\tt Day} (datatype)}{232} \indexentry{ctDay@{\tt ctDay}}{232} \indexentry{ctHour@{\tt ctHour}}{232} \indexentry{ctMin@{\tt ctMin}}{232} \indexentry{ctIsDST@{\tt ctIsDST}}{232} \indexentry{CalendarTime@{\tt CalendarTime} (datatype)}{232} \indexentry{tdYear@{\tt tdYear}}{232} \indexentry{tdMonth@{\tt tdMonth}}{232} \indexentry{tdDay@{\tt tdDay}}{232} \indexentry{tdHour@{\tt tdHour}}{232} \indexentry{tdMin@{\tt tdMin}}{232} \indexentry{tdPicosec@{\tt tdPicosec}}{232} \indexentry{TimeDiff@{\tt TimeDiff} (datatype)}{232} \indexentry{getClockTime@{\tt getClockTime}}{233} \indexentry{addToClockTime@{\tt addToClockTime}}{233} \indexentry{diffClockTimes@{\tt diffClockTimes}}{233} \indexentry{toCalendarTime@{\tt toCalendarTime}}{233} \indexentry{toUTCTime@{\tt toUTCTime}}{233} \indexentry{toClockTime@{\tt toClockTime}}{233} \indexentry{calendarTimeToString@{\tt calendarTimeToString}}{233} \indexentry{formatCalendarTime@{\tt formatCalendarTime}}{233} \indexentry{Time@{\tt Time} (module)}{234} \indexentry{Ix@{\tt Ix} (module)}{234} \indexentry{Locale@{\tt Locale} (module)}{234} \indexentry{Char@{\tt Char} (module)}{234} \indexentry{ClockTime@{\tt ClockTime} (datatype)}{234} \indexentry{Month@{\tt Month} (datatype)}{234} \indexentry{Day@{\tt Day} (datatype)}{234} \indexentry{ctDay@{\tt ctDay}}{235} \indexentry{ctHour@{\tt ctHour}}{235} \indexentry{ctMin@{\tt ctMin}}{235} \indexentry{ctIsDST@{\tt ctIsDST}}{235} \indexentry{CalendarTime@{\tt CalendarTime} (datatype)}{235} \indexentry{tdYear@{\tt tdYear}}{235} \indexentry{tdMonth@{\tt tdMonth}}{235} \indexentry{tdDay@{\tt tdDay}}{235} \indexentry{tdHour@{\tt tdHour}}{235} \indexentry{tdMin@{\tt tdMin}}{235} \indexentry{tdPicosec@{\tt tdPicosec}}{235} \indexentry{TimeDiff@{\tt TimeDiff} (datatype)}{235} \indexentry{getClockTime@{\tt getClockTime}}{235} \indexentry{addToClockTime@{\tt addToClockTime}}{235} \indexentry{diffClockTimes@{\tt diffClockTimes}}{235} \indexentry{toCalendarTime@{\tt toCalendarTime}}{235} \indexentry{toUTCTime@{\tt toUTCTime}}{235} \indexentry{toClockTime@{\tt toClockTime}}{235} \indexentry{calendarTimeToString@{\tt calendarTimeToString}}{235} \indexentry{formatCalendarTime@{\tt formatCalendarTime}}{236} \indexentry{to12@{\tt to12}}{236} \indexentry{show2@{\tt show2}}{237} \indexentry{show2'@{\tt show2'}}{237} \indexentry{show3@{\tt show3}}{237} \indexentry{locale}{239} \indexentry{Locale@{\tt Locale} (module)}{239} \indexentry{dateTimeFmt@{\tt dateTimeFmt}}{239} \indexentry{dateFmt@{\tt dateFmt}}{239} \indexentry{timeFmt@{\tt timeFmt}}{239} \indexentry{time12Fmt@{\tt time12Fmt}}{239} \indexentry{TimeLocale@{\tt TimeLocale} (datatype)}{239} \indexentry{defaultTimeLocale@{\tt defaultTimeLocale}}{239} \indexentry{Locale@{\tt Locale} (module)}{240} \indexentry{dateTimeFmt@{\tt dateTimeFmt}}{240} \indexentry{dateFmt@{\tt dateFmt}}{240} \indexentry{timeFmt@{\tt timeFmt}}{240} \indexentry{time12Fmt@{\tt time12Fmt}}{240} \indexentry{TimeLocale@{\tt TimeLocale} (datatype)}{240} \indexentry{defaultTimeLocale@{\tt defaultTimeLocale}}{240} \indexentry{CPU time}{241} \indexentry{execution time}{241} \indexentry{CPUTime@{\tt CPUTime} (module)}{241} \indexentry{getCPUTime@{\tt getCPUTime}}{241} \indexentry{cpuTimePrecision@{\tt cpuTimePrecision}}{241} \indexentry{Random@{\tt Random} (module)}{244} \indexentry{genRange@{\tt genRange}}{244} \indexentry{next@{\tt next}}{244} \indexentry{split@{\tt split}}{244} \indexentry{StdGen@{\tt StdGen} (datatype)}{244} \indexentry{mkStdGen@{\tt mkStdGen}}{244} \indexentry{randomR@{\tt randomR}}{244} \indexentry{random@{\tt random}}{244} \indexentry{randomRs@{\tt randomRs}}{244} \indexentry{randoms@{\tt randoms}}{244} \indexentry{randomRIO@{\tt randomRIO}}{244} \indexentry{randomIO@{\tt randomIO}}{244} \indexentry{newStdGen@{\tt newStdGen}}{244} \indexentry{setStdGen@{\tt setStdGen}}{244} \indexentry{getStdGen@{\tt getStdGen}}{244} \indexentry{getStdRandom@{\tt getStdRandom}}{244} \indexentry{next@{\tt next}}{245} \indexentry{split@{\tt split}}{245} \indexentry{genRange@{\tt genRange}}{245} \indexentry{RandomGen@{\tt RandomGen}}{245} \indexentry{StdGen@{\tt StdGen} (datatype)}{246} \indexentry{mkStdGen@{\tt mkStdGen}}{246} \indexentry{Random@{\tt Random} (class)}{247} \indexentry{random@{\tt random}}{247} \indexentry{randomR@{\tt randomR}}{247} \indexentry{randoms@{\tt randoms}}{247} \indexentry{randomRs@{\tt randomRs}}{247} \indexentry{randomIO@{\tt randomIO}}{247} \indexentry{randomRIO@{\tt randomRIO}}{247} \indexentry{setStdGen@{\tt setStdGen}}{248} \indexentry{getStdGen@{\tt getStdGen}}{248} \indexentry{newStdGen@{\tt newStdGen}}{248} \indexentry{getStdRandom@{\tt getStdRandom}}{248} \indexentry{application!function|see{function application}}{249} \indexentry{application!operator|see{operator application}}{249} \indexentry{binding!function|see{function binding}}{249} \indexentry{binding!pattern|see{pattern binding}}{249} \indexentry{binding!simple pattern|see{simple pattern binding}}{249} \indexentry{character set!ASCII|see{ASCII character set}}{249} \indexentry{character set!transparent|see{transparent character set}}{249} \indexentry{datatype!abstract|see{abstract datatype}}{249} \indexentry{datatype!algebraic|see{algebraic datatype}}{249} \indexentry{datatype!declaration|see{{\tt data} declaration}}{249} \indexentry{datatype!recursive|see{recursive datatype}}{249} \indexentry{datatype!renaming|see{{\tt newtype} declaration}}{249} \indexentry{declaration!datatype|see{{\tt data} declaration}}{249} \indexentry{declaration!class|see{class declaration}}{249} \indexentry{declaration!instance|see{instance declaration}}{249} \indexentry{declaration!default|see{{\tt default} declaration}}{249} \indexentry{declaration!import|see{import declaration}}{249} \indexentry{declaration!fixity|see{fixity declaration}}{249} \indexentry{environment!class|see{class environment}}{249} \indexentry{environment!type|see{type environment}}{249} \indexentry{expression!type|see{type expression}}{249} \indexentry{expression!conditional|see{conditional expression}}{249} \indexentry{expression!unit|see{unit expression}}{249} \indexentry{expression!let|see{let expression}}{249} \indexentry{expression!case|see{case expression}}{249} \indexentry{expression!simple case|see{simple case expression}}{249} \indexentry{"@-pattern@{\tt {\char'100}}|see{as-pattern}}{249} \indexentry{_@{\tt {\char'137}}|see{wildcard pattern}}{249} \indexentry{pattern!"@-pattern@{\tt {\char'100}}|see{as-pattern}}{249} \indexentry{pattern!_@{\tt {\char'137}}|see{wildcard pattern}}{249} \indexentry{pattern!constructed|see{constructed pattern}}{249} \indexentry{pattern!integer|see{integer literal pattern}}{249} \indexentry{pattern!floating|see{floating literal pattern}}{249} \indexentry{pattern!linear|see{linear pattern}}{249} \indexentry{pattern!n+k@\mbox{$\it n\makebox{\tt +}k$}|see{\mbox{$\it n\makebox{\tt +}k$} pattern}}{249} \indexentry{pattern!irrefutable|see{irrefutable pattern}}{249} \indexentry{pattern!refutable|see{refutable pattern}}{249} \indexentry{semantics!formal|see{formal semantics}}{249} \indexentry{string!transparent|see{transparent string}}{249} \indexentry{type!ambiguous|see{ambiguous type}}{249} \indexentry{type!monomorphic|see{monomorphic type}}{249} \indexentry{type!principal|see{principal type}}{249} \indexentry{type!trivial|see{trivial type}}{249} \indexentry{type!numeric|see{numeric type}}{249} \indexentry{type!function|see{function type}}{249} \indexentry{type!constructed|see{constructed type}}{249} \indexentry{type!tuple|see{tuple type}}{249} \indexentry{type!list|see{list type}}{249} \indexentry{type renaming|see{{\tt newtype} declaration}}{249} \indexentry{type signature!for an expression|see{expression type-signature}}{249} \indexentry{(aaa)@{\tt ()}|see{trivial type and unit expression}}{249} \indexentry{-@{\tt -}|hseealso{negation}}{249} \indexentry{+@{\tt +}|hseealso{\mbox{$\it n\makebox{\tt +}k$} pattern}}{249} \indexentry{\\@{\tt {\char'134}}|see{lambda abstraction}}{249} \indexentry{~@{\tt {\char'176}}|see{irrefutable pattern}}{249} \indexentry{derived instance|hseealso{instance declaration}}{249} \indexentry{if-then-else expression|see{conditional expression}}{249} \indexentry{instance declaration|hseealso{derived instance}}{249} \indexentry{layout|hseealso{off-side rule}}{249} \indexentry{off-side rule|hseealso{layout}}{249} \indexentry{method|see{class method}}{249} \indexentry{overloaded pattern|see{pattern-matching}}{249} \indexentry{precedence|hseealso{fixity}}{249} \indexentry{section|hseealso{operator application}}{249} \indexentry{signature|see{type signature}}{249} \indexentry{standard prelude|hseealso{{\tt Prelude}}}{249} \indexentry{synonym|see{type synonym}}{249} \indexentry{type class|see{class}}{249} \indexentry{type synonym|hseealso{datatype}}{249} \indexentry{unit datatype|see{trivial type}}{249} \indexentry{name!qualified|see{qualified name}}{249} \indexentry{name!special|see{special name}}{249} haskell98-report-20080907/report/complex.verb0000644000175000017500000000335711345221573020313 0ustar marcotmarcot%**The Haskell 98 Library Report: Complex Numbers %**~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 haskell98-report-20080907/report/iso-chars.verb0000644000175000017500000001203211345221573020522 0ustar marcotmarcot\newcommand{\Thorn}{Thorn} \newcommand{\thorn}{thorn} \newcommand{\Eth}{D\hspace{-7pt}@-@\hspace{2pt}} \newcommand{\eth}{{\tt d\hspace{-2pt}}\bar{ }\hspace{2pt}} \newcommand{\macron}{\bar{ }} \newcommand{\currency}{currency} \newcommand{\registered}{{\tiny R}\hspace{-8pt}{$\bigcirc$}\hspace{2pt}} \newcommand{\cents}{@c@\hspace{-5pt}{@|@}\hspace{2pt}} \newcommand{\degree}{^{\circ}} \newcommand{\pilcrow}{pilcrow} \newcommand{\yen}{Y\hspace{-5pt}$_{^{=}}$\hspace{2pt}} \newcommand{\male}{^a} \newcommand{\female}{^o} \newcommand{\brokenline}{\stackrel{_{\mid}}{_{_{\mid}}}} \newcommand{\isoacute}{\tt \acute{ }} \newcounter{four} \setcounter{four}{4} \newcommand{\isosectionmark}{\fnsymbol{four}} \newcounter{five} \setcounter{five}{5} \newcommand{\isoparamark}{\fnsymbol{five}} \newcommand{\ISOiexcl}{\mbox{\tt !`}} \newcommand{\ISOcent}{\mbox{$\tt \cents$}} \newcommand{\ISOcurren}{\mbox{$\currency$}} \newcommand{\ISOpound}{\mbox{\pounds{}}} \newcommand{\ISOyen}{\mbox{\tt \yen}} \newcommand{\ISObrkbar}{\mbox{{$\tt \brokenline$}}} \newcommand{\ISOsect}{\mbox{$\isosectionmark$}} \newcommand{\ISOuml}{\mbox{${\tt \ddot{ }}$}} \newcommand{\ISOcopy}{\mbox{${\tt \copyright}$}} \newcommand{\ISOordf}{\mbox{$\male$}} \newcommand{\ISOlaquo}{\mbox{$\ll$}} \newcommand{\ISOnot}{\mbox{$\neg$}} \newcommand{\ISOshy}{\mbox{${\tt -}$}} \newcommand{\ISOreg}{\mbox{$${\tt \registered}$$}} \newcommand{\ISOhibar}{\mbox{${\tt \macron}$}} \newcommand{\ISOdeg}{\mbox{${\tt \degree}$}} \newcommand{\ISOplusmn}{\mbox{$\pm$}} \newcommand{\ISOsuptwo}{\mbox{$^2$}} \newcommand{\ISOsupthree}{\mbox{$^3$}} \newcommand{\ISOacute}{\mbox{$\isoacute$}} \newcommand{\ISOmicro}{\mbox{$\mu$}} \newcommand{\ISOpara}{\mbox{$\isoparamark$}} \newcommand{\ISOmiddot}{\mbox{$\cdot$}} \newcommand{\ISOcedil}{\mbox{$${\tt \c{ }}$$}} \newcommand{\ISOsupone}{\mbox{$^1$}} \newcommand{\ISOordm}{\mbox{$\female$}} \newcommand{\ISOraquo}{\mbox{$\gg$}} \newcommand{\ISOfracfourth}{\mbox{$\frac{1}{4}$}} \newcommand{\ISOfrachalf}{\mbox{$\frac{1}{2}$}} \newcommand{\ISOfracthreeforths}{\mbox{$\frac{3}{4}$}} \newcommand{\ISOiquest}{\mbox{$${\tt ?`}$$}} \newcommand{\ISOtimes}{\mbox{$\times$}} \newcommand{\ISOdivide}{\mbox{$\div$}} \newcommand{\ISOagrave}{\mbox{${\tt \grave{a}}$}} \newcommand{\ISOaacute}{\mbox{${\tt \acute{a}}$}} \newcommand{\ISOacirc}{\mbox{${\tt \hat{a}}$}} \newcommand{\ISOatilde}{\mbox{${\tt \tilde{a}}$}} \newcommand{\ISOauml}{\mbox{${\tt \ddot{a}}$}} \newcommand{\ISOaring}{\mbox{$${\tt \aa}$$}} \newcommand{\ISOaelig}{\mbox{$${\tt \ae}$$}} \newcommand{\ISOccedil}{\mbox{$${\tt \c{c}}$$}} \newcommand{\ISOegrave}{\mbox{${\tt \grave{e}}$}} \newcommand{\ISOeacute}{\mbox{${\tt \acute{e}}$}} \newcommand{\ISOecirc}{\mbox{${\tt \hat{e}}$}} \newcommand{\ISOeuml}{\mbox{${\tt \ddot{e}}$}} \newcommand{\ISOigrave}{\mbox{${\tt \grave{\i}}$}} \newcommand{\ISOiacute}{\mbox{${\tt \acute{\i}}$}} \newcommand{\ISOicirc}{\mbox{${\tt \hat{\i}}$}} \newcommand{\ISOiuml}{\mbox{${\tt \ddot{\i}}$}} \newcommand{\ISOeth}{\mbox{$\eth$}} \newcommand{\ISOntilde}{\mbox{${\tt \tilde{n}}$}} \newcommand{\ISOograve}{\mbox{${\tt \grave{o}}$}} \newcommand{\ISOoacute}{\mbox{${\tt \acute{o}}$}} \newcommand{\ISOocirc}{\mbox{${\tt \hat{o}}$}} \newcommand{\ISOotilde}{\mbox{${\tt \tilde{o}}$}} \newcommand{\ISOouml}{\mbox{${\tt \ddot{o}}$}} \newcommand{\ISOoslash}{\mbox{${\tt \o}$}} \newcommand{\ISOugrave}{\mbox{${\tt \grave{u}}$}} \newcommand{\ISOuacute}{\mbox{${\tt \acute{u}}$}} \newcommand{\ISOucirc}{\mbox{${\tt \hat{u}}$}} \newcommand{\ISOuuml}{\mbox{${\tt \ddot{u}}$}} \newcommand{\ISOyacute}{\mbox{${\tt \acute{y}}$}} \newcommand{\ISOthorn}{\mbox{$\thorn$}} \newcommand{\ISOyuml}{\mbox{${\tt \ddot{y}}$}} \newcommand{\ISOAgrave}{\mbox{${\tt \grave{A}}$}} \newcommand{\ISOAacute}{\mbox{${\tt \acute{A}}$}} \newcommand{\ISOAcirc}{\mbox{${\tt \hat{A}}$}} \newcommand{\ISOAtilde}{\mbox{${\tt \tilde{A}}$}} \newcommand{\ISOAuml}{\mbox{${\tt \ddot{A}}$}} \newcommand{\ISOAring}{\mbox{$${\tt \AA}$$}} \newcommand{\ISOAElig}{\mbox{$${\tt \AE}$$}} \newcommand{\ISOCcedil}{\mbox{$${\tt \c{C}}$$}} \newcommand{\ISOEgrave}{\mbox{${\tt \grave{E}}$}} \newcommand{\ISOEacute}{\mbox{${\tt \acute{E}}$}} \newcommand{\ISOEcirc}{\mbox{${\tt \hat{E}}$}} \newcommand{\ISOEuml}{\mbox{${\tt \ddot{E}}$}} \newcommand{\ISOIgrave}{\mbox{${\tt \grave{I}}$}} \newcommand{\ISOIacute}{\mbox{${\tt \acute{I}}$}} \newcommand{\ISOIcirc}{\mbox{${\tt \hat{I}}$}} \newcommand{\ISOIuml}{\mbox{${\tt \ddot{I}}$}} \newcommand{\ISOETH}{\mbox{${\tt \Eth}$}} \newcommand{\ISONtilde}{\mbox{${\tt \tilde{N}}$}} \newcommand{\ISOOgrave}{\mbox{${\tt \grave{O}}$}} \newcommand{\ISOOacute}{\mbox{${\tt \acute{O}}$}} \newcommand{\ISOOcirc}{\mbox{${\tt \hat{O}}$}} \newcommand{\ISOOtilde}{\mbox{${\tt \tilde{O}}$}} \newcommand{\ISOOuml}{\mbox{${\tt \ddot{O}}$}} \newcommand{\ISOOslash}{\mbox{${\tt \O}$}} \newcommand{\ISOUgrave}{\mbox{${\tt \grave{U}}$}} \newcommand{\ISOUacute}{\mbox{${\tt \acute{U}}$}} \newcommand{\ISOUcirc}{\mbox{${\tt \hat{U}}$}} \newcommand{\ISOUuml}{\mbox{${\tt \ddot{U}}$}} \newcommand{\ISOYacute}{\mbox{${\tt \acute{Y}}$}} \newcommand{\ISOTHORN}{\mbox{$\Thorn$}} \newcommand{\ISOszlig}{\mbox{$${\tt \ss}$$}} haskell98-report-20080907/report/numeric.verb0000644000175000017500000000724111345221573020302 0ustar marcotmarcot%**The Haskell 98 Library Report: Numerics %**~header \section{Numeric} \label{lib-numeric} \outline{ \inputHS{lib-hdrs/Numeric} } This library contains assorted numeric functions, many of which are used in the standard Prelude. In what follows, recall the following type definitions from the @Prelude@: \bprog @ type ShowS = String -> String type ReadS = String -> [(a,String)] @ \eprog \subsection{Showing functions} \begin{itemize} \item @showSigned :: (Real a) => (a -> ShowS) -> Int -> a -> ShowS@ \\ converts a possibly-negative @Real@ value of type @a@ to a string. In the call "(@showSigned@ ~show ~prec ~val)", "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 @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@ \\ @ :: (RealFloat a) => Maybe Int -> a -> ShowS@ \\ These three functions all show signed @RealFloat@ values: \begin{itemize} \item @showFFloat@ uses standard decimal notation (e.g. @245000@, @0.0015@). \item @showEFloat@ uses scientific (exponential) notation (e.g. @2.45e2@, @1.5e-3@). \item @showGFloat@ uses standard decimal notation for arguments whose absolute value lies between @0.1@ and @9,999,999@, and scientific notation otherwise. \end{itemize} In the call "(@showEFloat@ ~digs ~val)", if "digs" is @Nothing@, the value is shown to full precision; if "digs" is "@Just@~ d", then at most "d" digits after the decimal point are shown. Exactly the same applies to the "digs" argument of the other two functions. \item @floatToDigits :: (RealFloat a) => Integer -> a -> ([Int], Int)@ \\ converts a base and a value to the representation of the value in digits, plus an exponent. More specifically, if $$ @floatToDigits@~b~r = @([@d_1, d_2, ... d_n@], @e@)@ $$ then the following properties hold: \begin{itemize} \item $r = 0.d_1 d_2 ..., d_n ~*~ b^e$ \item $n \geq 0$ \item $d_1 \neq 0 ~ \mbox{(when $n > 0$)}$ \item $0 \leq d_i \leq b-1$ \end{itemize} \end{itemize} \subsection{Reading functions} \begin{itemize} \item @readSigned :: (Real a) => ReadS a -> ReadS a@ \\ reads a {\em signed} @Real@ value, given a reader for an unsigned value. \item @readInt :: (Integral a) => a -> (Char->Bool) -> (Char->Int) -> ReadS a@ \\ reads an {\em unsigned} @Integral@ value in an arbitrary base. In the call "(@readInt@~ base ~isdig ~d2i)", "base" is the base, "isdig" is a predicate distinguishing valid digits in this base, and "d2i" converts a valid digit character to an @Int@. \item @readFloat :: (RealFrac a) => ReadS a@ \\ reads an {\em unsigned} @RealFrac@ value, expressed in decimal scientific notation. \item @readDec, readOct, readHex :: (Integral a) => ReadS a@ \\ each read an unsigned number, in decimal, octal, and hexadecimal notation respectively. 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} \begin{itemize} \item @fromRat :: (RealFloat a) => Rational -> a@ converts a @Rational@ value into any type in class @RealFloat@. \end{itemize} \subsection{Library {\tt Numeric}} \inputHS{lib-code/Numeric} %**~footer haskell98-report-20080907/report/syntax-iso.verb0000644000175000017500000006113111345221573020754 0ustar marcotmarcot% % $Header: /home/cvs/root/haskell-report/report/syntax-iso.verb,v 1.12 2003/01/13 13:08:56 simonpj Exp $ % %**Haskell 98 Syntax %**~header \section{Syntax Reference} \label{syntax} \index{syntax} \subsection{Notational Conventions} These notational conventions are used for presenting syntax: \[\ba{cl} "[pattern]" & \tr{optional} \\ "\{pattern\}" & \tr{zero or more repetitions} \\ "(pattern)" & \tr{grouping} \\ "pat_1 | pat_2" & \tr{choice} \\ "pat_{\langle{}pat'\rangle{}}" & \tr{difference---elements generated by "pat"} \\ & \tr{except those generated by "pat'"} \\ "@fibonacci@" & \tr{terminal syntax in typewriter font} \ea\] BNF-like syntax is used throughout, with productions having the form: @@@ nonterm -> alt_1 | alt_2 | ... | alt_n @@@ There are some families of nonterminals indexed by precedence levels (written as a superscript). Similarly, the nonterminals "op", "varop", and "conop" may have a double index: a letter "l", "r", or "n" for left-, right- or nonassociativity and a precedence level. A precedence-level variable "i" ranges from 0 to 9; an associativity variable "a" varies over "\{l, r, n\}". Thus, for example @@@ aexp -> @(@ exp^{i+1} qop^{(a,i)} @)@ @@@ actually stands for 30 productions, with 10 substitutions for "i" and 3 for "a". In both the lexical and the context-free syntax, there are some ambiguities that are to be resolved by making grammatical phrases as long as possible, proceeding from left to right (in shift-reduce parsing, resolving shift/reduce conflicts by shifting). In the lexical syntax, this is the ``maximal munch'' rule\index{maximal munch rule}. In the context-free syntax, this means that conditionals, let-expressions, and lambda abstractions extend to the right as far as possible. % here we input a list of the main changes in version 1.1 % \input{syntax-changes-11} %*anchor on \subsection{Lexical Syntax} % This covers only part of the lexical syntax. The rest is directly % included since it is much more scattered. \input{syntax-lexical} @@@ varid -> (small \{small | large | digit | @'@ \})_{\langle{}reservedid\rangle{}} conid -> large \{small | large | digit | @'@ \} reservedid -> @case@ | @class@ | @data@ | @default@ | @deriving@ | @do@ | @else@ | @if@ | @import@ | @in@ | @infix@ | @infixl@ | @infixr@ | @instance@ | @let@ | @module@ | @newtype@ | @of@ | @then@ | @type@ | @where@ | @_@ varsym -> ( symbol \{symbol | @:@\} )_{\langle{}reservedop | dashes\rangle{}} consym -> (@:@ \{symbol | @:@\})_{\langle{}reservedop\rangle{}} reservedop -> @..@ | @:@ | @::@ | @=@ | @\@ | @|@ | @<-@ | @->@ | {\tt @@} | @~@ | @=>@ varid && (\tr{variables}) conid && (\tr{constructors}) tyvar -> varid & (\tr{type variables}) tycon -> conid & (\tr{type constructors}) tycls -> conid & (\tr{type classes}) modid -> conid & (\tr{modules}) qvarid -> [ modid @.@ ] varid qconid -> [ modid @.@ ] conid qtycon -> [ modid @.@ ] tycon qtycls -> [ modid @.@ ] tycls qvarsym -> [ modid @.@ ] varsym qconsym -> [ modid @.@ ] consym decimal -> digit\{digit\} octal -> octit\{octit\} hexadecimal -> hexit\{hexit\} integer -> decimal | @0o@ octal | @0O@ octal | @0x@ hexadecimal | @0X@ hexadecimal float -> decimal @.@ decimal [exponent] | decimal exponent exponent -> (@e@ | @E@) [@+@ | @-@] decimal char -> @'@ (graphic_{\langle{}@'@ | @\@\rangle{}} | space | escape_{\langle{}@\&@\rangle{}}) @'@ string -> @"@ \{graphic_{\langle{}@"@ | @\@\rangle{}} | space | escape | gap\} @"@ escape -> @\@ ( charesc | ascii | decimal | @o@ octal | @x@ hexadecimal ) charesc -> @a@ | @b@ | @f@ | @n@ | @r@ | @t@ | @v@ | @\@ | @"@ | @'@ | @&@ ascii -> @^@cntrl | @NUL@ | @SOH@ | @STX@ | @ETX@ | @EOT@ | @ENQ@ | @ACK@ | @BEL@ | @BS@ | @HT@ | @LF@ | @VT@ | @FF@ | @CR@ | @SO@ | @SI@ | @DLE@ | @DC1@ | @DC2@ | @DC3@ | @DC4@ | @NAK@ | @SYN@ | @ETB@ | @CAN@ | @EM@ | @SUB@ | @ESC@ | @FS@ | @GS@ | @RS@ | @US@ | @SP@ | @DEL@ cntrl -> ascLarge | @@ | @[@ | @\@ | @]@ | @^@ | @_@ gap -> @\@ whitechar \{whitechar\} @\@ @@@ \indexsyn{varid}% \indexsyn{conid}% \indexsyn{reservedid}% \indexsyn{varsym}% \indexsyn{consym}% \indexsyn{symbol}% \indexsyn{reservedop}% \indexsyn{tyvar}% \indexsyn{tycon}% \indexsyn{tycls}% \indexsyn{modid}% \indexsyn{qvarid}% \indexsyn{qconid}% \indexsyn{qtycon}% \indexsyn{qtycls}% \indexsyn{qvarsym}% \indexsyn{qconsym}% \indexsyn{decimal}% \indexsyn{octal}% \indexsyn{hexadecimal}% \indexsyn{char}% \indexsyn{string}% \indexsyn{escape}% \indexsyn{charesc}% \indexsyn{ascii}% \indexsyn{cntrl}% \indexsyn{gap}% \subsection{Layout} \label{layout} \index{layout} Section~\ref{lexemes-layout} gives an informal discussion of the layout rule. This section defines it more precisely. The meaning of a Haskell program may depend on its {\em layout}. The effect of layout on its meaning can be completely described by adding braces and semicolons in places determined by the layout. The meaning of this augmented program is now layout insensitive. The effect of layout is specified in this section by describing how to add braces and semicolons to a laid-out program. The specification takes the form of a function "L" that performs the translation. The input to "L" is: \begin{itemize} \item A stream of lexemes as specified by the lexical syntax in the Haskell report, with the following additional tokens: \begin{itemize} \item If a @let@, @where@, @do@, or @of@ keyword is not followed by the lexeme @{@, the token "\{n\}" is inserted after the keyword, where "n" is the indentation of the next lexeme if there is one, or "0" if the end of file has been reached. \item If the first lexeme of a module is not @{@ or @module@, then it is preceded by "\{n\}" where "n" is the indentation of the lexeme. \item Where the start of a lexeme is preceded only by white space on the same line, this lexeme is preceded by "" where "n" is the indentation of the lexeme, provided that it is not, as a consequence of the first two rules, preceded by "\{n\}". (NB: a string literal may span multiple lines -- Section~\ref{lexemes-char}. So in the fragment \bprog @ f = ("Hello \ \Bill", "Jake") @ \eprog There is no "" inserted before the "@\Bill@", because it is not the beginning of a complete lexeme; nor before the "@,@", because it is not preceded only by white space.) \end{itemize} \item A stack of ``layout contexts'', in which each element is either: \begin{itemize} \item Zero, indicating that the enclosing context is explicit (i.e. the programmer supplied the opening brace. If the innermost context is 0, then no layout tokens will be inserted until either the enclosing context ends or a new context is pushed. \item A positive integer, which is the indentation column of the enclosing layout context. \end{itemize} \end{itemize} The ``indentation'' of a lexeme is the column number of the first character of that lexeme; the indentation of a line is the indentation of its leftmost lexeme. To determine the column number, assume a fixed-width font with the following conventions: \begin{itemize} \item The characters "newline", "return", "linefeed", and "formfeed", all start a new line. \item The first column is designated column 1, not 0. \item Tab stops are 8 characters apart. \item A tab character causes the insertion of enough spaces to align the current position with the next tab stop. \end{itemize} For the purposes of the layout rule, Unicode characters in a source program are considered to be of the same, fixed, width as an ASCII character. However, to avoid visual confusion, programmers should avoid writing programs in which the meaning of implicit layout depends on the width of non-space characters. The application \[ L~tokens~[] \] delivers a layout-insensitive translation of "tokens", where "tokens" is the result of lexically analysing a module and adding column-number indicators to it as described above. The definition of "L" is as follows, where we use ``":"'' as a stream construction operator, and ``"\emptystr"'' for the empty stream. % \begin{center} % \[\ba{lcll} % L~ (:ts)~ (m:ms) & = & @;@ ~:~ (L~ ts~(m:ms)) &\mbox{if}~ m = n \\ % & = & @}@ ~:~ (L~ (:ts)~ ms) & \mbox{if}~ n < m \\ % & = & L~ ts~(m:ms) & \mbox{otherwise} \\ % \\ % L~ (\{n\}:ts)~ (m:ms) & = & @{@ ~:~ (L~ ts~(n:m:ms)) & \mbox{if}~n > m~ (Note~ 1)\\ % & = & @{@ ~:~ @}@ ~:~ (L~ ts~(:m:ms)) & \mbox{otherwise}~ (Note~ 2)\\ % \\ % L~ (t:ts)~ (m:ms) & = & @}@ ~:~ (L~ (t:ts)~ ms) & \mbox{if}~ m /= 0 ~\mbox{and}~ \mbox{parse-error}(t) \\ % &&& (Note~ 3) \\ % \\ % L~ (@}@:ts)~ (0:ms) & = & @}@ ~:~ (L~ ts~ms) & (Note~ 4) \\ % \\ % L~ (@{@:ts)~ ms & = & @{@ ~:~ (L~ ts~(0:ms)) & (Note~ 5)\\ % \\ % L~ (t:ts)~ ms & = & t ~:~ (L~ ts~ms)\\ % \\ % L~ \emptystr~ [0] & = & \emptystr\\ % L~ \emptystr~ (m:ms) & = & @}@ ~:~ L~ \emptystr~ ms & \mbox{if}~m \neq 0~ (Note~ 6) % \ea\] % \end{center} \begin{center} \[\ba{lcll} L~ (:ts)~ (m:ms) & = & @;@ ~:~ (L~ ts~(m:ms)) &\mbox{if}~ m = n \\ & = & @}@ ~:~ (L~ (:ts)~ ms) & \mbox{if}~ n < m \\ L~ (:ts)~ms & = & L~ ts~ms \\ \\ L~ (\{n\}:ts)~ (m:ms) & = & @{@ ~:~ (L~ ts~(n:m:ms)) & \mbox{if}~n > m~ (Note~ 1)\\ L~ (\{n\}:ts)~ [] & = & @{@ ~:~ (L~ ts~[n]) & \mbox{if}~n > 0~ (Note~ 1)\\ L~ (\{n\}:ts)~ ms & = & @{@ ~:~ @}@ ~:~ (L~ (:ts)~ms) & (Note~ 2)\\ \\ L~ (@}@:ts)~ (0:ms) & = & @}@ ~:~ (L~ ts~ms) & (Note~ 3) \\ L~ (@}@:ts)~ ms & = & \mbox{parse-error} & (Note~ 3) \\ \\ L~ (@{@:ts)~ ms & = & @{@ ~:~ (L~ ts~(0:ms)) & (Note~ 4)\\ \\ L~ (t:ts)~ (m:ms) & = & @}@ ~:~ (L~ (t:ts)~ ms) & \mbox{if}~ m /= 0 ~\mbox{and}~ \mbox{parse-error}(t) \\ &&& (Note~ 5) \\ L~ (t:ts)~ ms & = & t ~:~ (L~ ts~ms)\\ \\ L~ \emptystr~ [] & = & \emptystr\\ L~ \emptystr~ (m:ms) & = & @}@ ~:~ L~ \emptystr~ ms & \mbox{if}~m \neq 0~ (Note~ 6) \ea\] \end{center} \begin{description} \item[Note 1.] A nested context must be further indented than the enclosing context ("n>m"). If not, "L" fails, and the compiler should indicate a layout error. An example is: \bprog @ f x = let h y = let p z = z in p in h @ \eprog Here, the definition of @p@ is indented less than the indentation of the enclosing context, which is set in this case by the definition of @h@. \item[Note 2.] If the first token after a @where@ (say) is not indented more than the enclosing layout context, then the block must be empty, so empty braces are inserted. The $\{n\}$ token is replaced by $$, to mimic the situation if the empty braces had been explicit. \item[Note 3.] By matching against 0 for the current layout context, we ensure that an explicit close brace can only match an explicit open brace. A parse error results if an explicit close brace matches an implicit open brace. \item[Note 4.] This clause means that all brace pairs are treated as explicit layout contexts, including labelled construction and update (Section~\ref{field-ops}). This is a difference between this formulation and Haskell 1.4. \item[Note 5.] The side condition "\mbox{parse-error}(t)" is to be interpreted as follows: if the tokens generated so far by "L" together with the next token "t" represent an invalid prefix of the Haskell grammar, and the tokens generated so far by "L" followed by the token ``@}@'' represent a valid prefix of the Haskell grammar, then "\mbox{parse-error}(t)" is true. The test $m /= 0$ checks that an implicitly-added closing brace would match an implicit open brace. \item[Note 6.] At the end of the input, any pending close-braces are inserted. It is an error at this point to be within a non-layout context (i.e.~ "m = 0"). \end{description} If none of the rules given above matches, then the algorithm fails. It can fail for instance when the end of the input is reached, and a non-layout context is active, since the close brace is missing. Some error conditions are not detected by the algorithm, although they could be: for example @let }@. Note 1 implements the feature that layout processing can be stopped prematurely by a parse error. For example \bprog @ let x = e; y = x in e' @ \eprog is valid, because it translates to \bprog @ let { x = e; y = x } in e' @ \eprog The close brace is inserted due to the parse error rule above. The parse-error rule is hard to implement in its full generality, because doing so involves fixities. For example, the expression \bprog @ do a == b == c @ \eprog has a single unambiguous (albeit probably type-incorrect) parse, namely \bprog @ (do { a == b }) == c @ \eprog because @(==)@ is non-associative. Programmers are therefore advised to avoid writing code that requires the parser to insert a closing brace in such situations. \startnewsection \subsection{Literate comments} \label{literate} \index{literate comments} The ``literate comment'' convention, first developed by Richard Bird and Philip Wadler for Orwell, and inspired in turn by Donald Knuth's ``literate programming'', is an alternative style for encoding \Haskell{} source code. The literate style encourages comments by making them the default. A line in which ``@>@'' is the first character is treated as part of the program; all other lines are comment. The program text is recovered by taking only those lines beginning with ``@>@'', and replacing the leading ``@>@'' with a space. Layout and comments apply exactly as described in Chapter~\ref{syntax} in the resulting text. To capture some cases where one omits an ``@>@'' by mistake, it is an error for a program line to appear adjacent to a non-blank comment line, where a line is taken as blank if it consists only of whitespace. By convention, the style of comment is indicated by the file extension, with ``@.hs@'' indicating a usual Haskell file and ``@.lhs@'' indicating a literate Haskell file. Using this style, a simple factorial program would be: \bprog @ This literate program prompts the user for a number and prints the factorial of that number: > main :: IO () > main = do putStr "Enter a number: " > l <- readLine > putStr "n!= " > print (fact (read l)) This is the factorial function. > fact :: Integer -> Integer > fact 0 = 1 > fact n = n * fact (n-1) @ \eprog An alternative style of literate programming is particularly suitable for use with the LaTeX text processing system. In this convention, only those parts of the literate program that are entirely enclosed between @\begin{code}@$\ldots$@\end{code}@ delimiters are treated as program text; all other lines are comment. More precisely: \begin{itemize} \item Program code begins on the first line following a line that begins @\begin{code}@. \item Program code ends just before a subsequent line that begins @\end{code}@ (ignoring string literals, of course). \end{itemize} It is not necessary to insert additional blank lines before or after these delimiters, though it may be stylistically desirable. For example, \bprog @ \documentstyle{article} \begin{document} \section{Introduction} This is a trivial program that prints the first 20 factorials. \begin{code} main :: IO () main = print [ (n, product [1..n]) | n <- [1..20]] \end{code} \end{document} @ \eprog This style uses the same file extension. It is not advisable to mix these two styles in the same file. \startnewsection \subsection{Context-Free Syntax} \label{bnf} @@@ module -> @module@ modid [exports] @where@ body | body body -> @{@ impdecls @;@ topdecls @}@ | @{@ impdecls @}@ | @{@ topdecls @}@ impdecls -> impdecl_1 @;@ ... @;@ impdecl_n & (n>=1) @@@ \indexsyn{module}% \indexsyn{body}% \indexsyn{modid}% \indexsyn{impdecls}% @@@ exports -> @(@ export_1 @,@ ... @,@ export_n [ @,@ ] @)@ & (n>=0) export -> qvar | qtycon [@(..)@ | @(@ cname_1 @,@ ... @,@ cname_n @)@] & (n>=0) | qtycls [@(..)@ | @(@ qvar_1 @,@ ... @,@ qvar_n @)@] & (n>=0) | @module@ modid @@@ \indexsyn{exports}% \indexsyn{export}% @@@ impdecl -> @import@ [@qualified@] modid [@as@ modid] [impspec] | & (\tr{empty declaration}) impspec -> @(@ import_1 @,@ ... @,@ import_n [ @,@ ] @)@ & (n>=0) | @hiding@ @(@ import_1 @,@ ... @,@ import_n [ @,@ ] @)@ & (n>=0) import -> var | tycon [ @(..)@ | @(@ cname_1 @,@ ... @,@ cname_n @)@] & (n>=0) | tycls [@(..)@ | @(@ var_1 @,@ ... @,@ var_n @)@] & (n>=0) cname -> var | con @@@ \indexsyn{impdecl}% \indexsyn{impspec}% \indexsyn{import}% \indexsyn{cname}% @@@ topdecls -> topdecl_1 @;@ ... @;@ topdecl_n & (n>=0) topdecl -> @type@ simpletype @=@ type | @data@ [context @=>@] simpletype @=@ constrs [deriving] | @newtype@ [context @=>@] simpletype @=@ newconstr [deriving] | @class@ [scontext @=>@] tycls tyvar [@where@ cdecls] | @instance@ [scontext @=>@] qtycls inst [@where@ idecls] | @default@ @(@type_1 @,@ ... @,@ type_n@)@ & (n>=0) | decl @@@ \indexsyn{topdecls}% \indexsyn{topdecl}% @@@ decls -> @{@ decl_1 @;@ ... @;@ decl_n @}@ & (n>=0) decl -> gendecl | (funlhs | pat^0) rhs cdecls -> @{@ cdecl_1 @;@ ... @;@ cdecl_n @}@ & (n>=0) cdecl -> gendecl | (funlhs | var) rhs idecls -> @{@ idecl_1 @;@ ... @;@ idecl_n @}@ & (n>=0) idecl -> (funlhs | var) rhs | & (\tr{empty}) gendecl -> vars @::@ [context @=>@] type & (\tr{type signature}) | fixity [integer] ops & (\tr{fixity declaration}) | & (\tr{empty declaration}) ops -> op_1 @,@ ... @,@ op_n & (n>=1) vars -> var_1 @,@ ...@,@ var_n & (n>=1) fixity -> @infixl@ | @infixr@ | @infix@ @@@ \indexsyn{vars}% \indexsyn{fixity}% \indexsyn{ops}% \indexsyn{gendecl}% \indexsyn{decls}% \indexsyn{decl}% \indexsyn{cdecls}% \indexsyn{cdecl}% \indexsyn{idecls}% \indexsyn{idecl}% @@@ type -> btype [@->@ type] & (\tr{function type}) btype -> [btype] atype & (\tr{type application}) atype -> gtycon | tyvar | @(@ type_1 @,@ ... @,@ type_k @)@ & (\tr{tuple type}, k>=2) | @[@ type @]@ & (\tr{list type}) | @(@ type @)@ & (\tr{parenthesized constructor}) gtycon -> qtycon | @()@ & (\tr{unit type}) | @[]@ & (\tr{list constructor}) | @(->)@ & (\tr{function constructor}) | @(,@\{@,@\}@)@ & (\tr{tupling constructors}) context -> class | @(@ class_1 @,@ ... @,@ class_n @)@ & (n>=0) class -> qtycls tyvar | qtycls @(@ tyvar atype_1 ... atype_n @)@ & (n>=1) scontext -> simpleclass | @(@ simpleclass_1 @,@ ... @,@ simpleclass_n @)@ & (n>=0) simpleclass -> qtycls tyvar @@@ \indexsyn{type}% \indexsyn{btype}% \indexsyn{atype}% \indexsyn{gtycon}% \indexsyn{context}% \indexsyn{class}% \indexsyn{simpleclass}% \indexsyn{scontext}% @@@ simpletype -> tycon tyvar_1 ... tyvar_k & (k>=0) constrs -> constr_1 @|@ ... @|@ constr_n & (n>=1) constr -> con [@!@] atype_1 ... [@!@] atype_k & (\tr{arity} con = k, k>=0) | (btype | @!@ atype) conop (btype | @!@ atype) & (\tr{infix} conop) | con @{@ fielddecl_1 @,@ ... @,@ fielddecl_n @}@ & (n>=0) newconstr -> con atype | con @{@ var @::@ type @}@ fielddecl -> vars @::@ (type | @!@ atype) deriving -> @deriving@ (dclass | @(@dclass_1@,@ ... @,@ dclass_n@)@)& (n>=0) dclass -> qtycls @@@ \indexsyn{simpletype}% \indexsyn{constrs}% \indexsyn{constr}% \indexsyn{fielddecl}% \indexsyn{deriving}% \indexsyn{dclass}% \indexsyn{newconstr}% @@@ inst -> gtycon | @(@ gtycon tyvar_1 ... tyvar_k @)@ & (k>=0, tyvars \tr{distinct}) | @(@ tyvar_1 @,@ ... @,@ tyvar_k @)@ & (k>=2, tyvars \tr{distinct}) | @[@ tyvar @]@ | @(@ tyvar_1 @->@ tyvar_2 @)@ & tyvar_1 \tr{and} tyvar_2 \tr{distinct} @@@ \indexsyn{inst}% @@@ funlhs -> var apat \{ apat \} | pat^{i+1} varop^{(a,i)} pat^{i+1} | lpat^i varop^{({\rm{}l},i)} pat^{i+1} | pat^{i+1} varop^{({\rm{}r},i)} rpat^i | @(@ funlhs @)@ apat \{ apat \} rhs -> @=@ exp [@where@ decls] | gdrhs [@where@ decls] gdrhs -> gd @=@ exp [gdrhs] gd -> @|@ exp^0 @@@ \indexsyn{funlhs}% \indexsyn{rhs}% \indexsyn{gdrhs}% \indexsyn{gd}% @@@ exp -> exp^0 @::@ [context @=>@] type & (\tr{expression type signature}) | exp^0 exp^i -> exp^{i+1} [qop^{({\rm{}n},i)} exp^{i+1}] | lexp^i | rexp^i lexp^i -> (lexp^i | exp^{i+1}) qop^{({\rm{}l},i)} exp^{i+1} lexp^6 -> @-@ exp^7 rexp^i -> exp^{i+1} qop^{({\rm{}r},i)} (rexp^i | exp^{i+1}) exp^{10} -> @\@ apat_1 ... apat_n @->@ exp & (\tr{lambda abstraction}, n>=1) | @let@ decls @in@ exp & ({\tr{let expression}}) | @if@ exp @then@ exp @else@ exp & (\tr{conditional}) | @case@ exp @of@ @{@ alts @}@ & (\tr{case expression}) | @do@ @{@ stmts @}@ & (\tr{do expression}) | fexp fexp -> [fexp] aexp & (\tr{function application}) @@@ \indexsyn{exp}% \index{exp@@"exp^i"}% \index{lexp@@"lexp^i"}% \index{rexp@@"rexp^i"}% \indexsyn{fexp}% @@@ aexp -> qvar & (\tr{variable}) | gcon & (\tr{general constructor}) | literal | @(@ exp @)@ & (\tr{parenthesized expression}) | @(@ exp_1 @,@ ... @,@ exp_k @)@ & (\tr{tuple}, k>=2) | @[@ exp_1 @,@ ... @,@ exp_k @]@ & (\tr{list}, k>=1) | @[@ exp_1 [@,@ exp_2] @..@ [exp_3] @]@ & (\tr{arithmetic sequence}) | @[@ exp @|@ qual_1 @,@ ... @,@ qual_n @]@ & (\tr{list comprehension}, n>=1) | @(@ exp^{i+1} qop^{(a,i)} @)@ & (\tr{left section}) | @(@ lexp^{i} qop^{(l,i)} @)@ & (\tr{left section}) | @(@ qop^{(a,i)}_{\langle@-@\rangle} exp^{i+1} @)@ & (\tr{right section}) | @(@ qop^{(r,i)}_{\langle@-@\rangle} rexp^{i} @)@ & (\tr{right section}) | qcon @{@ fbind_1 @,@ ... @,@ fbind_n @}@ & (\tr{labeled construction}, n>=0) | aexp_{\langle{}qcon\rangle{}} @{@ fbind_1 @,@ ... @,@ fbind_n @}@ & (\tr{labeled update}, n >= 1) @@@ \indexsyn{aexp}% @@@ qual -> pat @<-@ exp & (\tr{generator}) | @let@ decls & (\tr{local declaration}) | exp & (\tr{guard}) alts -> alt_1 @;@ ... @;@ alt_n & (n>=1) alt -> pat @->@ exp [@where@ decls] | pat gdpat [@where@ decls] | & (empty alternative) gdpat -> gd @->@ exp [ gdpat ] stmts -> stmt_1 ... stmt_n exp [@;@] & (n>=0) stmt -> exp @;@ | pat @<-@ exp @;@ | @let@ decls @;@ | @;@ & (empty statement) fbind -> qvar @=@ exp @@@ \indexsyn{qual}% \indexsyn{alts}% \indexsyn{alt}% \indexsyn{gdpat}% \indexsyn{stmt}% \indexsyn{stmts}% \indexsyn{fbind}% @@@ pat -> var @+@ integer & (\tr{successor pattern}) | pat^0 pat^i -> pat^{i+1} [qconop^{({\rm{}n},i)} pat^{i+1}] | lpat^i | rpat^i lpat^i -> (lpat^i | pat^{i+1}) qconop^{({\rm{}l},i)} pat^{i+1} lpat^6 -> @-@ (integer | float) & (\tr{negative literal}) rpat^i -> pat^{i+1} qconop^{({\rm{}r},i)} (rpat^i | pat^{i+1}) pat^{10} -> apat | gcon apat_1 ... apat_k & (\tr{arity} gcon = k, k>=1) @@@ \indexsyn{pat}% \index{pat@@"pat^i"}% \index{lpat@@"lpat^i"}% \index{rpat@@"rpat^i"}% \indexsyn{fpat}% \indexsyn{fpats}% @@@ apat -> var [{\tt @@} apat] & (\tr{as pattern}) | gcon & (\tr{arity} gcon = 0) | qcon @{@ fpat_1 @,@ ... @,@ fpat_k @}@ & (\tr{labeled pattern}, k>=0) | literal | @_@ & (\tr{wildcard}) | @(@ pat @)@ & (\tr{parenthesized pattern}) | @(@ pat_1 @,@ ... @,@ pat_k @)@ & (\tr{tuple pattern}, k>=2) | @[@ pat_1 @,@ ... @,@ pat_k @]@ & (\tr{list pattern}, k>=1) | @~@ apat & (\tr{irrefutable pattern}) fpat -> qvar @=@ pat @@@ \indexsyn{apat}% @@@ gcon -> @()@ | @[]@ | @(,@\{@,@\}@)@ | qcon var -> varid | @(@ varsym @)@ & (\tr{variable}) qvar -> qvarid | @(@ qvarsym @)@ & (\tr{qualified variable}) con -> conid | @(@ consym @)@ & (\tr{constructor}) qcon -> qconid | @(@ gconsym @)@ & (\tr{qualified constructor}) varop -> varsym | \bkqB varid \bkqA & (\tr{variable operator}) qvarop -> qvarsym | \bkqB qvarid \bkqA & (\tr{qualified variable operator}) conop -> consym | \bkqB conid \bkqA & (\tr{constructor operator}) qconop -> gconsym | \bkqB qconid \bkqA & (\tr{qualified constructor operator}) op -> varop | conop & (\tr{operator}) qop -> qvarop | qconop & (\tr{qualified operator}) gconsym -> @:@ | qconsym @@@ \indexsyn{gcon}% \indexsyn{var}% \indexsyn{qvar}% \indexsyn{con}% \indexsyn{qcon}% \indexsyn{varop}% \indexsyn{qvarop}% \indexsyn{conop}% \indexsyn{qconop}% \indexsyn{op}% \indexsyn{qop}% %*anchor off % Local Variables: % mode: latex % End: %**~footer haskell98-report-20080907/report/modules.verb0000644000175000017500000006750211345221573020316 0ustar marcotmarcot% % $Header: /home/cvs/root/haskell-report/report/modules.verb,v 1.20 2003/01/13 13:08:56 simonpj Exp $ % %**The Haskell 98 Report: Modules %*section 5 %**~header \section{Modules} \label{modules} \index{module} A module defines a collection of values, datatypes, type synonyms, classes, etc.~(see Chapter~\ref{declarations}), in an environment created by a set of {\em imports} (resources brought into scope from other modules). It {\em exports} some of these resources, making them available to other modules. We use the term {\em entity}\index{entity} to refer to a value, type, or class defined in, imported into, or perhaps exported from a module. A \Haskell{} {\em program} is a collection of modules, one of which, by convention, must be called @Main@\indexmodule{Main} and must export the value @main@\indextt{main}. The {\em value} of the program is the value of the identifier @main@ in module @Main@, which must be a computation of type $@IO@~\tau$ for some type $\tau$ (see Chapter~\ref{io}). When the program is executed, the computation @main@ is performed, and its result (of type $\tau$) is discarded. Modules may reference other modules via explicit @import@ declarations, each giving the name of a module to be imported and specifying its entities to be imported. Modules may be mutually recursive. Modules are used for name-space control, and are not first class values. A multi-module Haskell program can be converted into a single-module program by giving each entity a unique name, changing all occurrences to refer to the appropriate unique name, and then concatenating all the module bodies\footnote{There are two minor exceptions to this statement. First, @default@ declarations scope over a single module (Section~\ref{default-decls}). Second, Rule 2 of the monomorphism restriction (Section~\ref{sect:monomorphism-restriction}) is affected by module boundaries. }. For example, here is a three-module program: \bprog @ module Main where import A import B main = A.f >> B.f module A where f = ... module B where f = ... @ \eprog It is equivalent to the following single-module program: \bprog @ module Main where main = af >> bf af = ... bf = ... @ \eprog Because they are allowed to be mutually recursive, modules allow a program to be partitioned freely without regard to dependencies. The name-space for modules themselves is flat, with each module being associated with a unique module name (which are \Haskell{} identifiers beginning with a capital letter; i.e.~"modid"). There is one distinguished module, @Prelude@, which is imported into all modules by default (see Section~\ref{standard-prelude}), plus a set of standard library modules that may be imported as required (see Part~\ref{libraries}). \subsection{Module Structure} \label{module-implementations} A module defines a mutually recursive scope containing declarations for value bindings, data types, type synonyms, classes, etc. (see Chapter~\ref{declarations}). @@@ module -> @module@ modid [exports] @where@ body | body body -> @{@ impdecls @;@ topdecls @}@ | @{@ impdecls @}@ | @{@ topdecls @}@ modid -> conid impdecls -> impdecl_1 @;@ ... @;@ impdecl_n & (n>=1) topdecls -> topdecl_1 @;@ ... @;@ topdecl_n & (n>=1) @@@ \indexsyn{module}% \indexsyn{body}% \indexsyn{modid}% \indexsyn{impdecls}% \indexsyn{topdecls}% A module begins with a header: the keyword @module@, the module name, and a list of entities (enclosed in round parentheses) to be exported. The header is followed by a possibly-empty list of @import@ declarations ("impdecls", Section~\ref{import}) that specify modules to be imported, optionally restricting the imported bindings. This is followed by a possibly-empty list of top-level declarations ("topdecls", Chapter~\ref{declarations}). An abbreviated form of module, consisting only of\index{abbreviated module} the module body, is permitted. If this is used, the header is assumed to be `@module Main(main) where@'. If the first lexeme in the abbreviated module is not a @{@, then the layout rule applies for the top level of the module. \subsection{Export Lists} \label{export} \index{export list} @@@ exports -> @(@ export_1 @,@ ... @,@ export_n [ @,@ ] @)@ & (n>=0) export -> qvar | qtycon [@(..)@ | @(@ cname_1 @,@ ... @,@ cname_n @)@] & (n>=0) | qtycls [@(..)@ | @(@ var_1 @,@ ... @,@ var_n @)@] & (n>=0) | @module@ modid cname -> var | con @@@ \indexsyn{exports}% \indexsyn{export}% An {\em export list} identifies the entities to be exported by a module declaration. A module implementation may only export an entity that it declares, or that it imports from some other module. If the export list is omitted, all values, types and classes defined in the module are exported, {\em but not those that are imported}. Entities in an export list may be named as follows: \begin{enumerate} \item A value, field name, or class method, whether declared in the module body or imported, may be named by giving the name of the value as a "qvarid", which must be in scope. Operators should be enclosed in parentheses to turn them into "qvarid"s. \item An algebraic datatype "T" \index{algebraic datatype} declared by a @data@ or @newtype@ declaration may be named in one of three ways: \begin{itemize} \item The form "T" names the type {\em but not the constructors or field names}. The ability to export a type without its constructors allows the construction of abstract datatypes (see Section~\ref{abstract-types}). \item The form $T@(@c_1@,@\ldots@,@c_n@)@$, names the type and some or all of its constructors and field names. % Restriction removed March 02: % The subordinate names $c_i$ must not contain duplicates. \item The abbreviated form "T@(..)@" names the type and all its constructors and field names that are currently in scope (whether qualified or not). \end{itemize} In all cases, the (possibly-qualified) type constructor "T" must be in scope. The constructor and field names $c_i$ in the second form are unqualified; one of these subordinate names is legal if and only if (a) it names a constructor or field of "T", and (b) the constructor or field is in scope in the module body {\em regardless of whether it is in scope under a qualified or unqualified name}. For example, the following is legal \bprog @ module A( Mb.Maybe( Nothing, Just ) ) where import qualified Maybe as Mb @ \eprog Data constructors cannot be named in export lists except as subordinate names, because they cannot otherwise be distinguished from type constructors. \item A type synonym "T" declared by a @type@ declaration may be named by the form "T", where "T" is in scope. \index{type synonym} \item \index{class declaration} A class $C$ with operations $f_1,\ldots,f_n$ declared in a @class@ declaration may be named in one of three ways: \begin{itemize} \item The form "C" names the class {\em but not the class methods}. \item The form $C@(@f_1@,@\ldots@,@f_n@)@$, names the class and some or all of its methods. % Restriction removed March 02: % The subordinate names $f_i$ must not contain duplicates. \item The abbreviated form $C@(..)@$ names the class and all its methods that are in scope (whether qualified or not). \end{itemize} In all cases, "C" must be in scope. In the second form, one of the (unqualified) subordinate names $f_i$ is legal if and only if (a) it names a class method of "C", and (b) the class method is in scope in the module body regardless of whether it is in scope under a qualified or unqualified name. \item The form ``@module M@'' names the set of all entities that are in scope with both an unqualified name ``@e@'' and a qualified name ``@M.e@''. This set may be empty. For example: \bprog @ module Queue( module Stack, enqueue, dequeue ) where import Stack ... @ \eprog Here the module @Queue@ uses the module name @Stack@ in its export list to abbreviate all the entities imported from @Stack@. A module can name its own local definitions in its export list using its own name in the ``@module M@'' syntax, because a local declaration brings into scope both a qualified and unqualified name (Section~\ref{qualifiers}). For example: \bprog @ module Mod1( module Mod1, module Mod2 ) where import Mod2 import Mod3 @ \eprog Here module @Mod1@ exports all local definitions as well as those imported from @Mod2@ but not those imported from @Mod3@. It is an error to use @module M@ in an export list unless @M@ is the module bearing the export list, or @M@ is imported by at least one import declaration (qualified or unqualified). \end{enumerate} Exports lists are cumulative: the set of entities exported by an export list is the union of the entities exported by the individual items of the list. It makes no difference to an importing module how an entity was exported. For example, a field name @f@ from data type @T@ may be exported individually (@f@, item (1) above); or as an explicitly-named member of its data type (@T(f)@, item (2)); or as an implicitly-named member (@T(..)@, item(2)); or by exporting an entire module (@module M@, item (5)). The {\em unqualified} names of the entities exported by a module must all be distinct (within their respective namespace). For example \bprog @ module A ( C.f, C.g, g, module B ) where -- an invalid module import B(f) import qualified C(f,g) g = f True @ \eprog There are no name clashes within module @A@ itself, but there are name clashes in the export list between @C.g@ and @g@ (assuming @C.g@ and @g@ are different entities -- remember, modules can import each other recursively), and between @module B@ and @C.f@ (assuming @B.f@ and @C.f@ are different entities). \subsection{Import Declarations} \label{import} \index{import declaration} @@@ impdecl -> @import@ [@qualified@] modid [@as@ modid] [impspec] | & (empty declaration) impspec -> @(@ import_1 @,@ ... @,@ import_n [ @,@ ] @)@ & (n>=0) | @hiding@ @(@ import_1 @,@ ... @,@ import_n [ @,@ ] @)@ & (n>=0) import -> var | tycon [ @(..)@ | @(@ cname_1 @,@ ... @,@ cname_n @)@] & (n>=0) | tycls [@(..)@ | @(@ var_1 @,@ ... @,@ var_n @)@] & (n>=0) cname -> var | con @@@ % var % | tycon % | tycon @(..)@ % | tycon @(@ con_1 @,@ ... @,@ con_n@)@ & (n>=1) % | tycls @(..)@ % | tycls @(@ var_1 @,@ ... @,@ var_n@)@ & (n>=0) \indexsyn{impdecl}% \indexsyn{impspec}% \indexsyn{import}% \indexsyn{cname}% The entities exported by a module may be brought into scope in another module with an @import@ declaration at the beginning of the module. The @import@ declaration names the module to be imported and optionally specifies the entities to be imported. A single module may be imported by more than one @import@ declaration. Imported names serve as top level declarations: they scope over the entire body of the module but may be shadowed by local non-top-level bindings. The effect of multiple @import@ declarations is strictly cumulative: an entity is in scope if it is imported by any of the @import@ declarations in a module. The ordering of import declarations is irrelevant. Lexically, the terminal symbols ``@as@'', ``@qualified@'' and ``@hiding@'' are each a "varid" rather than a "reservedid". They have special significance only in the context of an @import@ declaration; they may also be used as variables. \subsubsection{What is imported} \label{whatisimported} Exactly which entities are to be imported can be specified in one of the following three ways:\nopagebreak[4] \begin{enumerate} \item The imported entities can be specified explicitly by listing them in parentheses. Items in the list have the same form as those in export lists, except qualifiers are not permitted and the `@module@ "modid"' entity is not permitted. When the @(..)@ form of import is used for a type or class, the @(..)@ refers to all of the constructors, methods, or field names exported from the module. The list must name only entities exported by the imported module. The list may be empty, in which case nothing except the instances is imported. \item Entities can be excluded by using the form @hiding(@"import_1 @,@ ... @,@ import_n" @)@,\index{hiding} which specifies that all entities exported by the named module should be imported except for those named in the list. Data constructors may be named directly in hiding lists without being prefixed by the associated type. Thus, in \bprog @ import M hiding (C) @ \eprog any constructor, class, or type named @C@ is excluded. In contrast, using @C@ in an import list names only a class or type. It is an error to hide an entity that is not, in fact, exported by the imported module. \item Finally, if "impspec" is omitted then all the entities exported by the specified module are imported. \end{enumerate} \subsubsection{Qualified import} \index{qualified name} For each entity imported under the rules of Section~\ref{whatisimported}, the top-level environment is extended. If the import declaration used the @qualified@ keyword, only the {\em qualified name} of the entity is brought into scope. If the @qualified@ keyword is omitted, then {\em both} the qualified {\em and} unqualified name of the entity is brought into scope. Section~\ref{qualifiers} describes qualified names in more detail. The qualifier on the imported name is either the name of the imported module, or the local alias given in the @as@ clause (Section~\ref{as-clause}) on the @import@ statement. Hence, {\em the qualifier is not necessarily the name of the module in which the entity was originally declared}. The ability to exclude the unqualified names allows full programmer control of the unqualified namespace: a locally defined entity can share the same name as a qualified import: \par {\small \bprog @ module Ring where import qualified Prelude -- All Prelude names must be qualified import List( nub ) l1 + l2 = l1 Prelude.++ l2 -- This + differs from the one in the Prelude l1 * l2 = nub (l1 + l2) -- This * differs from the one in the Prelude succ = (Prelude.+ 1) @ \eprog } \subsubsection{Local aliases} \label{as-clause} Imported modules may be assigned a local alias in the importing module using the @as@ clause. For example, in \bprog @ import qualified VeryLongModuleName as C @ \eprog entities must be referenced using `@C.@' as a qualifier instead of `@VeryLongModuleName.@'. This also allows a different module to be substituted for @VeryLongModuleName@ without changing the qualifiers used for the imported module. It is legal for more than one module in scope to use the same qualifier, provided that all names can still be resolved unambiguously. For example: \bprog @ module M where import qualified Foo as A import qualified Baz as A x = A.f @ \eprog This module is legal provided only that @Foo@ and @Baz@ do not both export @f@. An @as@ clause may also be used on an un-@qualified@ @import@ statement: \bprog @ import Foo as A(f) @ \eprog This declaration brings into scope @f@ and @A.f@. \subsubsection{Examples} To clarify the above import rules, suppose the module @A@ exports @x@ and @y@. Then this table shows what names are brought into scope by the specified import statement: \begin{center} \begin{tabular}{|ll|} \hline Import declaration & Names brought into scope \\ \hline @import A@ & @x@, @y@, @A.x@, @A.y@ \\ @import A()@ & (nothing) \\ @import A(x)@ & @x@, @A.x@ \\ @import qualified A@ & @A.x@, @A.y@ \\ @import qualified A()@ & (nothing) \\ @import qualified A(x)@ & @A.x@ \\ @import A hiding ()@ & @x@, @y@, @A.x@, @A.y@ \\ @import A hiding (x)@ & @y@, @A.y@ \\ @import qualified A hiding ()@ & @A.x@, @A.y@ \\ @import qualified A hiding (x)@ & @A.y@ \\ @import A as B@ & @x@, @y@, @B.x@, @B.y@ \\ @import A as B(x)@ & @x@, @B.x@ \\ @import qualified A as B@ & @B.x@, @B.y@ \\ \hline \end{tabular} \end{center} In all cases, all instance declarations in scope in module @A@ are imported (Section~\ref{import-instances}). \subsection{Importing and Exporting Instance Declarations} \label{import-instances} \index{instance declaration!importing and exporting} Instance declarations cannot be explicitly named on import or export lists. All instances in scope within a module are {\em always} exported and any import brings {\em all} instances in from the imported module. Thus, an instance declaration is in scope if and only if a chain of @import@ declarations leads to the module containing the instance declaration. For example, @import M()@ does not bring any new names in scope from module @M@, but does bring in any instances visible in @M@. A module whose only purpose is to provide instance declarations can have an empty export list. For example \bprog @ module MyInstances() where instance Show (a -> b) where show fn = "<>" instance Show (IO a) where show io = "<>" @ \eprog \subsection{Name Clashes and Closure} \subsubsection{Qualified names}\index{qualified name} \label{qualifiers} A {\em qualified name} is written as "modid"@.@"name" (Section~\ref{ids}). A qualified name is brought into scope: \begin{itemize} \item {\em By a top level declaration.} A top-level declaration brings into scope both the unqualified {\em and} the qualified name of the entity being defined. Thus: \bprog @ module M where f x = ... g x = M.f x x @ \eprog is legal. The {\em defining} occurrence must mention the {\em unqualified} name; therefore, it is illegal to write \bprog @ module M where M.f x = ... -- ILLEGAL g x = let M.y = x+1 in ... -- ILLEGAL @ \eprog \item {\em By an @import@ declaration.} An @import@ declaration, whether @qualified@ or not, always brings into scope the qualified name of the imported entity (Section~\ref{import}). This allows a qualified import to be replaced with an unqualified one without forcing changes in the references to the imported names. \end{itemize} \subsubsection{Name clashes} If a module contains a bound occurrence of a name, such as @f@ or @A.f@, it must be possible unambiguously to resolve which entity is thereby referred to; that is, there must be only one binding for @f@ or @A.f@ respectively. It is {\em not} an error for there to exist names that cannot be so resolved, provided that the program does not mention those names. For example: \bprog @ module A where import B import C tup = (b, c, d, x) module B( d, b, x, y ) where import D x = ... y = ... b = ... module C( d, c, x, y ) where import D x = ... y = ... c = ... module D( d ) where d = ... @ \eprog Consider the definition of @tup@. \begin{itemize} \item The references to @b@ and @c@ can be unambiguously resolved to @b@ declared in @B@, and @c@ declared in @C@ respectively. \item The reference to @d@ is unambiguously resolved to @d@ declared in @D@. In this case the same entity is brought into scope by two routes (the import of @B@ and the import of @C@), and can be referred to in @A@ by the names @d@, @B.d@, and @C.d@. \item The reference to @x@ is ambiguous: it could mean @x@ declared in @B@, or @x@ declared in @C@. The ambiguity could be fixed by replacing the reference to @x@ by @B.x@ or @C.x@. \item There is no reference to @y@, so it is not erroneous that distinct entities called @y@ are exported by both @B@ and @C@. An error is only reported if @y@ is actually mentioned. \end{itemize} The name occurring in a type signature or fixity declarations is always unqualified, and unambiguously refers to another declaration in the same declaration list (except that the fixity declaration for a class method can occur at top level --- Section~\ref{fixity}). For example, the following module is legal: \bprog @ module F where sin :: Float -> Float sin x = (x::Float) f x = Prelude.sin (F.sin x) @ \eprog The local declaration for @sin@ is legal, even though the Prelude function @sin@ is implicitly in scope. The references to @Prelude.sin@ and @F.sin@ must both be qualified to make it unambiguous which @sin@ is meant. However, the unqualified name "@sin@" in the type signature in the first line of @F@ unambiguously refers to the local declaration for @sin@. \subsubsection{Closure} \label{closure} \index{closure} Every module in a \Haskell{} program must be {\em closed}. That is, every name explicitly mentioned by the source code must be either defined locally or imported from another module. However, entities that the compiler requires for type checking or other compile time analysis need not be imported if they are not mentioned by name. The \Haskell{} compilation system is responsible for finding any information needed for compilation without the help of the programmer. That is, the import of a variable @x@ does not require that the datatypes and classes in the signature of @x@ be brought into the module along with @x@ unless these entities are referenced by name in the user program. The \Haskell{} system silently imports any information that must accompany an entity for type checking or any other purposes. Such entities need not even be explicitly exported: the following program is valid even though @T@ does not escape @M1@: \bprog @ module M1(x) where data T = T x = T module M2 where import M1(x) y = x @ \eprog In this example, there is no way to supply an explicit type signature for @y@ since @T@ is not in scope. Whether or not @T@ is explicitly exported, module @M2@ knows enough about @T@ to correctly type check the program. The type of an exported entity is unaffected by non-exported type synonyms. For example, in \bprog @ module M(x) where type T = Int x :: T x = 1 @ \eprog the type of @x@ is both @T@ and @Int@; these are interchangeable even when @T@ is not in scope. That is, the definition of @T@ is available to any module that encounters it whether or not the name @T@ is in scope. The only reason to export @T@ is to allow other modules to refer it by name; the type checker finds the definition of @T@ if needed whether or not it is exported. \subsection{Standard Prelude} \label{standard-prelude} \index{standard prelude} \index{libraries} Many of the features of \Haskell{} are defined in \Haskell{} itself as a library of standard datatypes, classes, and functions, called the ``Standard Prelude.'' In \Haskell{}, the Prelude is contained in the module @Prelude@.\indexmodule{Prelude} There are also many predefined library modules, which provide less frequently used functions and types. For example, complex numbers, arrays, and most of the input/output are all part of the standard libraries. These are defined in Part~\ref{libraries}. Separating libraries from the Prelude has the advantage of reducing the size and complexity of the Prelude, allowing it to be more easily assimilated, and increasing the space of useful names available to the programmer. Prelude and library modules differ from other modules in that their semantics (but not their implementation) are a fixed part of the \Haskell{} language definition. This means, for example, that a compiler may optimize calls to functions in the Prelude without consulting the source code of the Prelude. \subsubsection{The @Prelude@ Module} \indexmodule{Prelude} \index{Prelude!implicit import of} The @Prelude@ module is imported automatically into all modules as if by the statement `@import Prelude@', if and only if it is not imported with an explicit @import@ declaration. This provision for explicit import allows entities defined in the Prelude to be selectively imported, just like those from any other module. The semantics of the entities in @Prelude@ is specified by a reference implementation of @Prelude@ written in \Haskell{}, given in Chapter~\ref{stdprelude}. Some datatypes (such as @Int@) and functions (such as @Int@ addition) cannot be specified directly in \Haskell{}. Since the treatment of such entities depends on the implementation, they are not formally defined in Chapter~\ref{stdprelude}. The implementation of @Prelude@ is also incomplete in its treatment of tuples: there should be an infinite family of tuples and their instance declarations, but the implementation only gives a scheme. Chapter~\ref{stdprelude} defines the module @Prelude@ using several other modules: @PreludeList@, @PreludeIO@, and so on. These modules are {\em not} part of Haskell 98, and they cannot be imported separately. They are simply there to help explain the structure of the @Prelude@ module; they should be considered part of its implementation, not part of the language definition. \subsubsection{Shadowing Prelude Names} \label{std-prel-shadowing} The rules about the Prelude have been cast so that it is possible to use Prelude names for nonstandard purposes; however, every module that does so must have an @import@ declaration that makes this nonstandard usage explicit. For example: \bprog @ module A( null, nonNull ) where import Prelude hiding( null ) null, nonNull :: Int -> Bool null x = x == 0 nonNull x = not (null x) @ \eprog Module @A@ redefines @null@, and contains an unqualified reference to @null@ on the right hand side of @nonNull@. The latter would be ambiguous without the @hiding(null)@ on the @import Prelude@ statement. Every module that imports @A@ unqualified, and then makes an unqualified reference to @null@ must also resolve the ambiguous use of @null@ just as @A@ does. Thus there is little danger of accidentally shadowing Prelude names. It is possible to construct and use a different module to serve in place of the Prelude. Other than the fact that it is implicitly imported, the Prelude is an ordinary \Haskell{} module; it is special only in that some objects in the Prelude are referenced by special syntactic constructs. Redefining names used by the Prelude does not affect the meaning of these special constructs. For example, in \bprog @ module B where import Prelude() import MyPrelude f x = (x,x) g x = (,) x x h x = [x] ++ [] @ \eprog the explicit @import Prelude()@ declaration prevents the automatic import of @Prelude@, while the declaration @import MyPrelude@ brings the non-standard prelude into scope. The special syntax for tuples (such as @(x,x)@ and @(,)@) and lists (such as @[x]@ and @[]@) continues to refer to the tuples and lists defined by the standard @Prelude@; there is no way to redefine the meaning of @[x]@, for example, in terms of a different implementation of lists. On the other hand, the use of @++@ is not special syntax, so it refers to @++@ imported from @MyPrelude@. It is not possible, however, to hide @instance@ declarations in the @Prelude@. For example, one cannot define a new instance for @Show Char@. \subsection{Separate Compilation} \index{separate compilation} Depending on the \Haskell{} implementation used, separate compilation of mutually recursive modules may require that imported modules contain additional information so that they may be referenced before they are compiled. Explicit type signatures for all exported values may be necessary to deal with mutual recursion. The precise details of separate compilation are not defined by this report. \subsection{Abstract Datatypes} \label{abstract-types} \index{abstract datatype} The ability to export a datatype without its constructors allows the construction of abstract datatypes (ADTs). For example, an ADT for stacks could be defined as: \bprog @ module Stack( StkType, push, pop, empty ) where data StkType a = EmptyStk | Stk a (StkType a) push x s = Stk x s pop (Stk _ s) = s empty = EmptyStk @ \eprog Modules importing @Stack@ cannot construct values of type @StkType@ because they do not have access to the constructors of the type. Instead, they must use @push@, @pop@, and @empty@ to construct such values. It is also possible to build an ADT on top of an existing type by using a @newtype@ declaration. For example, stacks can be defined with lists: \bprog @ module Stack( StkType, push, pop, empty ) where newtype StkType a = Stk [a] push x (Stk s) = Stk (x:s) pop (Stk (_:s)) = Stk s empty = Stk [] @ \eprogNoSkip %**~footer % Local Variables: % mode: latex % End: haskell98-report-20080907/report/preface-13.verb0000644000175000017500000003141311345221573020464 0ustar marcotmarcot% % $Header: /home/cvs/root/haskell-report/report/preface-13.verb,v 1.12 2002/12/02 11:22:02 simonpj Exp $ % %**The Haskell 98 Report: Preface %*section %**~sheader \markboth{PREFACE}{PREFACE} \begin{center} {\Large \bf Preface} \end{center} \vspace{.2in} \begin{quote} ``{\em Some half dozen persons have written technically on combinatory logic, and most of these, including ourselves, have published something erroneous. Since some of our fellow sinners are among the most careful and competent logicians on the contemporary scene, we regard this as evidence that the subject is refractory. Thus fullness of exposition is necessary for accuracy; and excessive condensation would be false economy here, even more than it is ordinarily.}'' \begin{flushright} Haskell B.~Curry and Robert Feys \\ in the Preface to {\em Combinatory Logic} \cite{curry&feys:book}, May 31, 1956 \end{flushright} \end{quote} \vspace{.2in} \noindent In September of 1987 a meeting was held at the conference on Functional Programming Languages and Computer Architecture (FPCA~'87) in Portland, Oregon, to discuss an unfortunate situation in the functional programming community: there had come into being more than a dozen non-strict, purely functional programming languages, all similar in expressive power and semantic underpinnings. There was a strong consensus at this meeting that more widespread use of this class of functional languages\index{functional language} was being hampered by the lack of a common language. It was decided that a committee should be formed to design such a language, providing faster communication of new ideas, a stable foundation for real applications development, and a vehicle through which others would be encouraged to use functional languages. This document describes the result of that committee's efforts: a purely functional programming language called \Haskell{}, \index{Haskell@@\Haskell{}} named after the logician Haskell B.~Curry\index{Curry, Haskell B.} whose work provides the logical basis for much of ours. \subsection{Goals} The committee's primary goal was to design a language that satisfied these constraints: \begin{enumerate} \item It should be suitable for teaching, research, and applications, including building large systems. \item It should be completely described via the publication of a formal syntax and semantics. \item It should be freely available. Anyone should be permitted to implement the language and distribute it to whomever they please. \item It should be based on ideas that enjoy a wide consensus. \item It should reduce unnecessary diversity in functional programming languages. \end{enumerate} The committee hopes that \Haskell{} can serve as a basis for future research in language design. We hope that extensions or variants of the language may appear, incorporating experimental features. \subsection{Haskell 98} Haskell has evolved continuously since its original publication. By the middle of 1997, there had been four versions of the language (the latest at that point being Haskell 1.4). At the 1997 Haskell Workshop in Amsterdam, it was decided that a stable variant of Haskell was needed; this stable language is the subject of this Report, and is called ``Haskell 98''. Haskell 98 was conceived as a relatively minor tidy-up of Haskell 1.4, making some simplifications, and removing some pitfalls for the unwary. It is intended to be a ``stable'' language in sense the {\em implementors are committed to supporting Haskell 98 exactly as specified, for the foreseeable future}. As a separate exercise, Haskell will continue to evolve. At the time of writing there are Haskell implementations that support existential types, local universal polymorphism, rank-2 types, multi-parameter type classes, pattern guards, exceptions, concurrency, and more besides. Haskell 98 does not impede these developments. Instead, it provides a stable point of reference, so that those who wish to write text books, or use Haskell for teaching, can do so in the knowledge that Haskell 98 will continue to exist. On the few occasions when we refer to the evolving, future version of Haskell, we call it ``Haskell 2''. \subsection{This Report} This report is the official specification of \Haskell{} 98 and should be suitable for writing programs and building implementations. It is {\em not} a tutorial on programming in \Haskell{} such as the `Gentle Introduction' \cite{tutorial}, so some familiarity with functional languages is assumed. Haskell 98 is described in two separate documents: the Haskell Language Report (this document) and the Haskell Library Report \cite{libraries}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Highlights %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Evolutionary Highlights} For the benefit of those who have some knowledge of earlier version of Haskell, we briefly summarise the differences between Haskell 98 and its predecessors. \subsubsection{Highlights of the August 2001 Revision} Both Haskell 98 Reports were revised in August 2001, to incorporate dozens of typographical errors and presentational improvements. A complete list of all changes can be found at @http://haskell.org@. \subsubsection{Highlights of Haskell 98} A complete list of the differences between Haskell 1.4 and Haskell 98 can be found at @http://haskell.org@. A summary of the main features is as follows: \begin{itemize} \item List comprehensions have reverted to being list comprehensions, not monad comprehensions. \item There are several useful generalisations of the module system: name clashes are reported lazily, and distinct modules can share a local alias. \item Fixity declarations can appear anywhere a type signature can, and, like type signatures, bind to an entity rather than to its name. \item ``Punning'' for records has been removed. \item The class @Eval@ has been removed; @seq@ is now polymorphic. \item The type @Void@ has been removed. \end{itemize} \subsubsection{Highlights of Haskell 1.4} Version~1.4 of the report made the following relatively minor changes to the language: \begin{itemize} \item The character set has been changed to Unicode\index{Unicode character set}. \item List comprehensions have been generalized to arbitrary monads.\index{list comprehension} \item Import and export of class methods and constructors is no longer restricted to `all or nothing' as previously. Any subset of class methods or data constructors may be selected for import or export. Also, constructors and class methods can now be named directly on import and export lists instead of as components of a type or class. \item Qualified names may now be used as field names in patterns and updates. \item @Ord@ is no longer a superclass of @Enum@. Some of the default methods for @Enum@ have changed. \item Context restrictions on @newtype@ declarations have been relaxed. \index{newtype declaration@@{\tt newtype} declaration} \item The Prelude is now more explicit about some instances for @Read@ and @Show@. \item The fixity of @>>=@ has changed. \end{itemize} \subsubsection{Highlights of Haskell 1.3} Version~1.3 of the report made the following substantial changes to the language: \begin{itemize} \item Prelude and Library entities were distinguished, and the Library became a separate Report. \item Monadic I/O was introduced. \item Monadic programming was made more readable through the introduction of a special @do@ syntax. \item Constructor classes were introduced as a natural generalization of the original \Haskell{} type system, supporting polymorphism over type constructors. \item A number of enhancements were made to \Haskell{} type declarations, including: strictness annotations, labelled fields, and @newtype@ declarations. \item A number of changes to the module system were made. Instead of renaming, qualified names are used to resolve name conflicts. All names are now redefinable; there is no longer a @PreludeCore@ module containing names that cannot be reused. Interface files are no longer specified by this report; all issues of separate compilation are now left up to the implementation. \end{itemize} \subsection{The "n+k" Pattern Controversy} \index{n+k pattern@@"n@+@k" pattern} For technical reasons, many people feel that "n@+@k" patterns are an incongruous language design feature that should be eliminated from \Haskell{}. On the other hand, they serve as a vehicle for teaching introductory programming, in particular recursion over natural numbers. Alternatives to "n@+@k" patterns have been explored, but are too premature to include in \Haskell{} 98. Thus we decided to retain this feature at present but to discourage the use of "n@+@k" patterns by \Haskell{} users --- see Section~\ref{patterns}. This feature may be altered or removed in Haskell 2, and should be avoided. Implementors are encouraged to provide a mechanism for users to selectively enable or disable "n@+@k" patterns. % The De-Wadlerization flag! \subsection{\Haskell{} Resources} The Haskell web site \bprog @ http://haskell.org @ \eprog gives access to many useful resources, including: \begin{itemize} \item Online versions of the language and library definitions, including a complete list of all the differences between Haskell 98 and Haskell 1.4. \item Tutorial material on Haskell. \item Details of the Haskell mailing list. \item Implementations of Haskell. \item Contributed Haskell tools and libraries. \item Applications of Haskell. \end{itemize} Particularly relevant to this Report are the following two papers: \begin{itemize} \item ``A static semantics for Haskell'' (Faxen) gives a formal presentation of Haskell's type system \cite{faxen:static}. \item ``Typing Haskell in Haskell'' (Jones) gives a type inference algorithm for Haskell, written in Haskell \cite{jones:thih}. \end{itemize} We welcome your comments, suggestions, and criticisms on the language or its presentation in the report, via the Haskell mailing list. \subsection*{Acknowledgements} We heartily thank these people for their useful contributions to this report: Kris Aerts, Hans Aberg, Sten Anderson, Richard Bird, Stephen Blott, Tom Blenko, Duke Briscoe, Paul Callaghan, Magnus Carlsson, Manuel Chakravarty, Franklin Chen, Olaf Chitil, Chris Clack, Guy Cousineau, Tony Davie, Craig Dickson, Chris Dornan, Laura Dutton, Chris Fasel, Pat Fasel, Sigbjorn Finne, Michael Fryers, Andy Gill, Mike Gunter, Cordy Hall, Mark Hall, Thomas Hallgren, Matt Harden, Klemens Hemm, Fergus Henderson, Dean Herington, Ralf Hinze, Bob Hiromoto, Nic Holt, Ian Holyer, Randy Hudson, Alexander Jacobson, Patrick Jansson, Robert Jeschofnik, Orjan Johansen, Simon B.~Jones, Stef Joosten, Mike Joy, Stefan Kahrs, Antti-Juhani Kaijanaho, Jerzy Karczmarczuk, Wolfram Karl, Kent Karlsson, Richard Kelsey, Siau-Cheng Khoo, Amir Kishon, Feliks Kluzniak, Jan Kort, Marcin Kowalczyk, Jose Labra, Jeff Lewis, Mark Lillibridge, Bjorn Lisper, Sandra Loosemore, Pablo Lopez, Olaf Lubeck, Ian Lynagh, Christian Maeder, Ketil Malde, Simon Marlow, Michael Marte, Jim Mattson, John Meacham, Sergey Mechveliani, Erik Meijer, Gary Memovich, Randy Michelsen, Rick Mohr, Andy Moran, Arthur Norman, Nick North, Chris Okasaki, Bjarte M. {\O}stvold, Paul Otto, Sven Panne, Dave Parrott, Ross Paterson, Larne Pekowsky, Rinus Plasmeijer, Ian Poole, Stephen Price, John Robson, Andreas Rossberg, George Russell, Patrick Sansom, Felix Schroeter, Julian Seward, Nimish Shah, Christian Sievers, Libor Skarvada, Jan Skibinski, Lauren Smith, Raman Sundaresh, Ken Takusagawa, Satish Thatte, Simon Thompson, Tom Thomson, Tommy Thorn, Dylan Thurston, Mike Thyer, Mark Tullsen, David Tweed, Pradeep Varma, Malcolm Wallace, Keith Wansbrough, Tony Warnock, Michael Webber, Carl Witty, Stuart Wray, and Bonnie Yantis. We are especially grateful to past members of the \Haskell{} committee --- Arvind, Jon Fairbairn, Andy Gordon, Maria M. Guzman, Dick Kieburtz, Rishiyur Nikhil, Mike Reeve, David Wise, and Jonathan Young --- for the major contributions they have made to previous versions of this report. We also thank those who have participated in the lively discussions about \Haskell{} on the FP and \Haskell{} mailing lists. Finally, aside from the important foundational work laid by Church, Rosser, Curry, and others on the lambda calculus, we wish to acknowledge the influence of many noteworthy programming languages developed over the years. Although it is difficult to pinpoint the origin of many ideas, we particularly wish to acknowledge the influence of Lisp (and its modern-day incarnations Common Lisp and Scheme); Landin's ISWIM; APL; Backus's FP \cite{back78}; ML and Standard ML; Hope and Hope$^{+}$; Clean; Id; Gofer; Sisal; and Turner's series of languages culminating in Miranda.\footnote{{\rm Miranda} is a trademark of Research Software Ltd.} Without these forerunners \Haskell{} would not have been possible. %**~sfooter haskell98-report-20080907/report/lib-code/0000755000175000017500000000000011345221573017432 5ustar marcotmarcothaskell98-report-20080907/report/lib-code/Numeric.hs0000644000175000017500000003103611345221573021373 0ustar marcotmarcotmodule Numeric(fromRat, showSigned, showIntAtBase, showInt, showOct, showHex, readSigned, readInt, readDec, readOct, readHex, floatToDigits, showEFloat, showFFloat, showGFloat, showFloat, readFloat, lexDigits) where import Char ( isDigit, isOctDigit, isHexDigit , digitToInt, intToDigit ) import Ratio ( (%), numerator, denominator ) import Array ( (!), Array, array ) -- This converts a rational to a floating. This should be used in the -- Fractional instances of Float and Double. fromRat :: (RealFloat a) => Rational -> a fromRat x = if x == 0 then encodeFloat 0 0 -- Handle exceptional cases else if x < 0 then - fromRat' (-x) -- first. else fromRat' x -- Conversion process: -- Scale the rational number by the RealFloat base until -- it lies in the range of the mantissa (as used by decodeFloat/encodeFloat). -- Then round the rational to an Integer and encode it with the exponent -- that we got from the scaling. -- To speed up the scaling process we compute the log2 of the number to get -- a first guess of the exponent. fromRat' :: (RealFloat a) => Rational -> a fromRat' x = r where b = floatRadix r p = floatDigits r (minExp0, _) = floatRange r minExp = minExp0 - p -- the real minimum exponent xMin = toRational (expt b (p-1)) xMax = toRational (expt b p) p0 = (integerLogBase b (numerator x) - integerLogBase b (denominator x) - p) `max` minExp f = if p0 < 0 then 1 % expt b (-p0) else expt b p0 % 1 (x', p') = scaleRat (toRational b) minExp xMin xMax p0 (x / f) r = encodeFloat (round x') p' -- Scale x until xMin <= x < xMax, or p (the exponent) <= minExp. scaleRat :: Rational -> Int -> Rational -> Rational -> Int -> Rational -> (Rational, Int) scaleRat b minExp xMin xMax p x = if p <= minExp then (x, p) else if x >= xMax then scaleRat b minExp xMin xMax (p+1) (x/b) else if x < xMin then scaleRat b minExp xMin xMax (p-1) (x*b) else (x, p) -- Exponentiation with a cache for the most common numbers. minExpt = 0::Int maxExpt = 1100::Int expt :: Integer -> Int -> Integer expt base n = if base == 2 && n >= minExpt && n <= maxExpt then expts!n else base^n expts :: Array Int Integer expts = array (minExpt,maxExpt) [(n,2^n) | n <- [minExpt .. maxExpt]] -- Compute the (floor of the) log of i in base b. -- Simplest way would be just divide i by b until it's smaller then b, -- but that would be very slow! We are just slightly more clever. integerLogBase :: Integer -> Integer -> Int integerLogBase b i = if i < b then 0 else -- Try squaring the base first to cut down the number of divisions. let l = 2 * integerLogBase (b*b) i doDiv :: Integer -> Int -> Int doDiv i l = if i < b then l else doDiv (i `div` b) (l+1) in doDiv (i `div` (b^l)) l -- 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, 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 readSigned readPos = readParen False read' where read' r = read'' r ++ [(-x,t) | ("-",s) <- lex r, (x,t) <- read'' s] read'' r = [(n,s) | (str,s) <- lex r, (n,"") <- readPos str] -- readInt reads a string of digits using an arbitrary base. -- Leading minus signs must be handled elsewhere. readInt :: (Integral a) => a -> (Char -> Bool) -> (Char -> Int) -> ReadS a readInt radix isDig digToInt s = [(foldl1 (\n d -> n * radix + d) (map (fromIntegral . digToInt) ds), r) | (ds,r) <- nonnull isDig s ] -- Unsigned readers for various bases readDec, readOct, readHex :: (Integral a) => ReadS a readDec = readInt 10 isDigit digitToInt readOct = readInt 8 isOctDigit digitToInt readHex = readInt 16 isHexDigit digitToInt showEFloat :: (RealFloat a) => Maybe Int -> a -> ShowS showFFloat :: (RealFloat a) => Maybe Int -> a -> ShowS showGFloat :: (RealFloat a) => Maybe Int -> a -> ShowS showFloat :: (RealFloat a) => a -> ShowS showEFloat d x = showString (formatRealFloat FFExponent d x) showFFloat d x = showString (formatRealFloat FFFixed d x) showGFloat d x = showString (formatRealFloat FFGeneric d x) showFloat = showGFloat Nothing -- These are the format types. This type is not exported. data FFFormat = FFExponent | FFFixed | FFGeneric formatRealFloat :: (RealFloat a) => FFFormat -> Maybe Int -> a -> String formatRealFloat fmt decs x = s where base = 10 s = if isNaN x then "NaN" else if isInfinite x then if x < 0 then "-Infinity" else "Infinity" else if x < 0 || isNegativeZero x then '-' : doFmt fmt (floatToDigits (toInteger base) (-x)) else doFmt fmt (floatToDigits (toInteger base) x) doFmt fmt (is, e) = let ds = map intToDigit is in case fmt of FFGeneric -> doFmt (if e < 0 || e > 7 then FFExponent else FFFixed) (is, e) FFExponent -> case decs of Nothing -> case ds of [] -> "0.0e0" [d] -> d : ".0e" ++ show (e-1) d:ds -> d : '.' : ds ++ 'e':show (e-1) Just dec -> let dec' = max dec 1 in case is of [] -> '0':'.':take dec' (repeat '0') ++ "e0" _ -> let (ei, is') = roundTo base (dec'+1) is d:ds = map intToDigit (if ei > 0 then init is' else is') in d:'.':ds ++ "e" ++ show (e-1+ei) FFFixed -> case decs of Nothing -- Always prints a decimal point | e > 0 -> take e (ds ++ repeat '0') ++ '.' : mk0 (drop e ds) | otherwise -> "0." ++ mk0 (replicate (-e) '0' ++ ds) Just dec -> -- Print decimal point iff dec > 0 let dec' = max dec 0 in if e >= 0 then let (ei, is') = roundTo base (dec' + e) is (ls, rs) = splitAt (e+ei) (map intToDigit is') in mk0 ls ++ mkdot0 rs else let (ei, is') = roundTo base dec' (replicate (-e) 0 ++ is) d : ds = map intToDigit (if ei > 0 then is' else 0:is') in d : mkdot0 ds where mk0 "" = "0" -- Print 0.34, not .34 mk0 s = s mkdot0 "" = "" -- Print 34, not 34. mkdot0 s = '.' : s -- when the format specifies no -- digits after the decimal point roundTo :: Int -> Int -> [Int] -> (Int, [Int]) roundTo base d is = case f d is of (0, is) -> (0, is) (1, is) -> (1, 1 : is) where b2 = base `div` 2 f n [] = (0, replicate n 0) f 0 (i:_) = (if i >= b2 then 1 else 0, []) f d (i:is) = let (c, ds) = f (d-1) is i' = c + i in if i' == base then (1, 0:ds) else (0, i':ds) -- -- Based on "Printing Floating-Point Numbers Quickly and Accurately" -- by R.G. Burger and R. K. Dybvig, in PLDI 96. -- The version here uses a much slower logarithm estimator. -- It should be improved. -- This function returns a non-empty list of digits (Ints in [0..base-1]) -- and an exponent. In general, if -- floatToDigits r = ([a, b, ... z], e) -- then -- r = 0.ab..z * base^e -- floatToDigits :: (RealFloat a) => Integer -> a -> ([Int], Int) floatToDigits _ 0 = ([], 0) floatToDigits base x = let (f0, e0) = decodeFloat x (minExp0, _) = floatRange x p = floatDigits x b = floatRadix x minExp = minExp0 - p -- the real minimum exponent -- Haskell requires that f be adjusted so denormalized numbers -- will have an impossibly low exponent. Adjust for this. f :: Integer e :: Int (f, e) = let n = minExp - e0 in if n > 0 then (f0 `div` (b^n), e0+n) else (f0, e0) (r, s, mUp, mDn) = if e >= 0 then let be = b^e in if f == b^(p-1) then (f*be*b*2, 2*b, be*b, b) else (f*be*2, 2, be, be) else if e > minExp && f == b^(p-1) then (f*b*2, b^(-e+1)*2, b, 1) else (f*2, b^(-e)*2, 1, 1) k = let k0 = if b==2 && base==10 then -- logBase 10 2 is slightly bigger than 3/10 so -- the following will err on the low side. Ignoring -- the fraction will make it err even more. -- Haskell promises that p-1 <= logBase b f < p. (p - 1 + e0) * 3 `div` 10 else ceiling ((log (fromInteger (f+1)) + fromIntegral e * log (fromInteger b)) / log (fromInteger base)) fixup n = if n >= 0 then if r + mUp <= expt base n * s then n else fixup (n+1) else if expt base (-n) * (r + mUp) <= s then n else fixup (n+1) in fixup k0 gen ds rn sN mUpN mDnN = let (dn, rn') = (rn * base) `divMod` sN mUpN' = mUpN * base mDnN' = mDnN * base in case (rn' < mDnN', rn' + mUpN' > sN) of (True, False) -> dn : ds (False, True) -> dn+1 : ds (True, True) -> if rn' * 2 < sN then dn : ds else dn+1 : ds (False, False) -> gen (dn:ds) rn' sN mUpN' mDnN' rds = if k >= 0 then gen [] r (s * expt base k) mUp mDn else let bk = expt base (-k) in gen [] (r * bk) s (mUp * bk) (mDn * bk) in (map fromIntegral (reverse rds), k) -- This floating point reader uses a less restrictive syntax for floating -- point than the Haskell lexer. The `.' is optional. readFloat :: (RealFrac a) => ReadS a readFloat r = [(fromRational ((n%1)*10^^(k-d)),t) | (n,d,s) <- readFix r, (k,t) <- readExp s] ++ [ (0/0, t) | ("NaN",t) <- lex r] ++ [ (1/0, t) | ("Infinity",t) <- lex r] where readFix r = [(read (ds++ds'), length ds', t) | (ds,d) <- lexDigits r, (ds',t) <- lexFrac d ] lexFrac ('.':ds) = lexDigits ds lexFrac s = [("",s)] readExp (e:s) | e `elem` "eE" = readExp' s readExp s = [(0,s)] readExp' ('-':s) = [(-k,t) | (k,t) <- readDec s] readExp' ('+':s) = readDec s readExp' s = readDec s lexDigits :: ReadS String lexDigits = nonnull isDigit nonnull :: (Char -> Bool) -> ReadS String nonnull p s = [(cs,t) | (cs@(_:_),t) <- [span p s]] haskell98-report-20080907/report/lib-code/Random.hs0000644000175000017500000000611711345221573021213 0ustar marcotmarcotmodule Random ( RandomGen(next, split, genRange), StdGen, mkStdGen, Random( random, randomR, randoms, randomRs, randomIO, randomRIO ), getStdRandom, getStdGen, setStdGen, newStdGen ) where ---------------- The RandomGen class --------------------------- class RandomGen g where genRange :: g -> (Int, Int) next :: g -> (Int, g) split :: g -> (g, g) -- May not exist for all RandomGens ---------------- A standard instance of RandomGen --------------- data StdGen = ... -- Abstract instance RandomGen StdGen where ... -- The show/read instances provide a primitive way to save -- the state of a random number generator -- It is expected read (show g) == g instance Read StdGen where ... -- read succeeds on *any* string, not only those -- constructed with show. Hence you can use any -- string as way to construct a RandomGen. -- - read guarantees to consume a finite portion of -- the string -- - different strings are likely to result in -- different generators instance Show StdGen where ... mkStdGen :: Int -> StdGen -- Make a StdGen from an Int. Different Ints should result -- in different generators. ---------------- The Random class --------------------------- class Random a where randomR :: RandomGen g => (a, a) -> g -> (a, g) -- Returns a random value uniformly distributed in [lo,hi] -- It is unspecified what happens if lo > hi random :: RandomGen g => g -> (a, g) -- Return any value of type a. -- For bounded types, the range is normally the whole type -- For Fractional types, the range is normally [0..1] -- For Integer, the range is (arbitrarily) the range of Int randomRs :: RandomGen g => (a, a) -> g -> [a] randoms :: RandomGen g => g -> [a] randomIO :: IO a randomRIO :: (a,a) -> IO a -- Default methods randoms g = x : randoms g' where (x,g') = random g randomRs = ...similar... randomIO = getStdRandom random randomRIO range = getStdRandom (randomR range) instance Random Int where ... instance Random Integer where ... instance Random Float where ... instance Random Double where ... instance Random Bool where ... instance Random Char where ... ---------------- The global random generator --------------------------- -- There is a single, implicit, global random number generator -- of type StdGen, held in some global variable maintained by the IO monad -- -- It is initialised non-deterministically; to get -- deterministic behaviour use setStdGen. setStdGen :: StdGen -> IO () -- Set the global generator getStdGen :: IO StdGen -- Get the global generator getStdRandom :: (StdGen -> (a, StdGen)) -> IO a -- Use the supplied function to get a value from -- the current global random generator, g, and update the -- global generator with the new generator returned getStdRandom f = do g <- getStdGen let (val, g') = f g setStdGen g' return val newStdGen :: IO StdGen -- Apply split to the current global random generator -- update it with one of the results and return the other newStdGen = do g <- getStdGen let (s1,s2) = split g setStdGen s1 return s2 haskell98-report-20080907/report/lib-code/Ratio.hs0000644000175000017500000000741011345221573021046 0ustar marcotmarcot-- Standard functions on rational numbers module Ratio ( Ratio, Rational, (%), numerator, denominator, approxRational ) where infixl 7 % ratPrec = 7 :: Int data (Integral a) => Ratio a = !a :% !a deriving (Eq) type Rational = Ratio Integer (%) :: (Integral a) => a -> a -> Ratio a numerator, denominator :: (Integral a) => Ratio a -> a approxRational :: (RealFrac a) => a -> a -> Rational -- "reduce" is a subsidiary function used only in this module. -- It normalises a ratio by dividing both numerator -- and denominator by their greatest common divisor. -- -- E.g., 12 `reduce` 8 == 3 :% 2 -- 12 `reduce` (-8) == 3 :% (-2) reduce _ 0 = error "Ratio.% : zero denominator" reduce x y = (x `quot` d) :% (y `quot` d) where d = gcd x y x % y = reduce (x * signum y) (abs y) numerator (x :% _) = x denominator (_ :% y) = y instance (Integral a) => Ord (Ratio a) where (x:%y) <= (x':%y') = x * y' <= x' * y (x:%y) < (x':%y') = x * y' < x' * y instance (Integral a) => Num (Ratio a) where (x:%y) + (x':%y') = reduce (x*y' + x'*y) (y*y') (x:%y) * (x':%y') = reduce (x * x') (y * y') negate (x:%y) = (-x) :% y abs (x:%y) = abs x :% y signum (x:%y) = signum x :% 1 fromInteger x = fromInteger x :% 1 instance (Integral a) => Real (Ratio a) where toRational (x:%y) = toInteger x :% toInteger y instance (Integral a) => Fractional (Ratio a) where (x:%y) / (x':%y') = (x*y') % (y*x') recip (x:%y) = y % x fromRational (x:%y) = fromInteger x :% fromInteger y instance (Integral a) => RealFrac (Ratio a) where properFraction (x:%y) = (fromIntegral q, r:%y) where (q,r) = quotRem x y instance (Integral a) => Enum (Ratio a) where succ x = x+1 pred x = x-1 toEnum = fromIntegral fromEnum = fromInteger . truncate -- May overflow enumFrom = numericEnumFrom -- These numericEnumXXX functions enumFromThen = numericEnumFromThen -- are as defined in Prelude.hs enumFromTo = numericEnumFromTo -- but not exported from it! enumFromThenTo = numericEnumFromThenTo instance (Read a, Integral a) => Read (Ratio a) where readsPrec p = readParen (p > ratPrec) (\r -> [(x%y,u) | (x,s) <- readsPrec (ratPrec+1) r, ("%",t) <- lex s, (y,u) <- readsPrec (ratPrec+1) t ]) instance (Integral a) => Show (Ratio a) where showsPrec p (x:%y) = showParen (p > ratPrec) (showsPrec (ratPrec+1) x . showString " % " . showsPrec (ratPrec+1) y) approxRational x eps = simplest (x-eps) (x+eps) where simplest x y | y < x = simplest y x | x == y = xr | x > 0 = simplest' n d n' d' | y < 0 = - simplest' (-n') d' (-n) d | otherwise = 0 :% 1 where xr@(n:%d) = toRational x (n':%d') = toRational y simplest' n d n' d' -- assumes 0 < n%d < n'%d' | r == 0 = q :% 1 | q /= q' = (q+1) :% 1 | otherwise = (q*n''+d'') :% n'' where (q,r) = quotRem n d (q',r') = quotRem n' d' (n'':%d'') = simplest' d' r' d r haskell98-report-20080907/report/lib-code/Monad.hs0000644000175000017500000000554611345221573021036 0ustar marcotmarcotmodule Monad ( MonadPlus(mzero, mplus), join, guard, when, unless, ap, msum, filterM, mapAndUnzipM, zipWithM, zipWithM_, foldM, liftM, liftM2, liftM3, liftM4, liftM5, -- ...and what the Prelude exports Monad((>>=), (>>), return, fail), Functor(fmap), mapM, mapM_, sequence, sequence_, (=<<), ) where -- The MonadPlus class definition class (Monad m) => MonadPlus m where mzero :: m a mplus :: m a -> m a -> m a -- Instances of MonadPlus instance MonadPlus Maybe where mzero = Nothing Nothing `mplus` ys = ys xs `mplus` ys = xs instance MonadPlus [] where mzero = [] mplus = (++) -- Functions msum :: MonadPlus m => [m a] -> m a msum xs = foldr mplus mzero xs join :: (Monad m) => m (m a) -> m a join x = x >>= id when :: (Monad m) => Bool -> m () -> m () when p s = if p then s else return () unless :: (Monad m) => Bool -> m () -> m () unless p s = when (not p) s ap :: (Monad m) => m (a -> b) -> m a -> m b ap = liftM2 ($) guard :: MonadPlus m => Bool -> m () guard p = if p then return () else mzero mapAndUnzipM :: (Monad m) => (a -> m (b,c)) -> [a] -> m ([b], [c]) mapAndUnzipM f xs = sequence (map f xs) >>= return . unzip zipWithM :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m [c] zipWithM f xs ys = sequence (zipWith f xs ys) zipWithM_ :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m () zipWithM_ f xs ys = sequence_ (zipWith f xs ys) foldM :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a foldM f a [] = return a foldM f a (x:xs) = f a x >>= \ y -> foldM f y xs filterM :: Monad m => (a -> m Bool) -> [a] -> m [a] filterM p [] = return [] filterM p (x:xs) = do { b <- p x; ys <- filterM p xs; return (if b then (x:ys) else ys) } liftM :: (Monad m) => (a -> b) -> (m a -> m b) liftM f = \a -> do { a' <- a; return (f a') } liftM2 :: (Monad m) => (a -> b -> c) -> (m a -> m b -> m c) liftM2 f = \a b -> do { a' <- a; b' <- b; return (f a' b') } liftM3 :: (Monad m) => (a -> b -> c -> d) -> (m a -> m b -> m c -> m d) liftM3 f = \a b c -> do { a' <- a; b' <- b; c' <- c; return (f a' b' c') } liftM4 :: (Monad m) => (a -> b -> c -> d -> e) -> (m a -> m b -> m c -> m d -> m e) liftM4 f = \a b c d -> do { a' <- a; b' <- b; c' <- c; d' <- d; return (f a' b' c' d') } liftM5 :: (Monad m) => (a -> b -> c -> d -> e -> f) -> (m a -> m b -> m c -> m d -> m e -> m f) liftM5 f = \a b c d e -> do { a' <- a; b' <- b; c' <- c; d' <- d; e' <- e; return (f a' b' c' d' e') } haskell98-report-20080907/report/lib-code/Maybe.hs0000644000175000017500000000175411345221573021032 0ustar marcotmarcotmodule Maybe( isJust, isNothing, fromJust, fromMaybe, listToMaybe, maybeToList, catMaybes, mapMaybe, -- ...and what the Prelude exports Maybe(Nothing, Just), maybe ) where isJust :: Maybe a -> Bool isJust (Just a) = True isJust Nothing = False isNothing :: Maybe a -> Bool isNothing = not . isJust fromJust :: Maybe a -> a fromJust (Just a) = a fromJust Nothing = error "Maybe.fromJust: Nothing" fromMaybe :: a -> Maybe a -> a fromMaybe d Nothing = d fromMaybe d (Just a) = a maybeToList :: Maybe a -> [a] maybeToList Nothing = [] maybeToList (Just a) = [a] listToMaybe :: [a] -> Maybe a listToMaybe [] = Nothing listToMaybe (a:_) = Just a catMaybes :: [Maybe a] -> [a] catMaybes ms = [ m | Just m <- ms ] mapMaybe :: (a -> Maybe b) -> [a] -> [b] mapMaybe f = catMaybes . map f haskell98-report-20080907/report/lib-code/Complex.hs0000644000175000017500000000643411345221573021404 0ustar marcotmarcot module Complex(Complex((:+)), realPart, imagPart, conjugate, mkPolar, cis, polar, magnitude, phase) where infix 6 :+ data (RealFloat a) => Complex a = !a :+ !a deriving (Eq,Read,Show) realPart, imagPart :: (RealFloat a) => Complex a -> a realPart (x:+y) = x imagPart (x:+y) = y conjugate :: (RealFloat a) => Complex a -> Complex a conjugate (x:+y) = x :+ (-y) mkPolar :: (RealFloat a) => a -> a -> Complex a mkPolar r theta = r * cos theta :+ r * sin theta cis :: (RealFloat a) => a -> Complex a cis theta = cos theta :+ sin theta polar :: (RealFloat a) => Complex a -> (a,a) polar z = (magnitude z, phase z) magnitude :: (RealFloat a) => Complex a -> a magnitude (x:+y) = scaleFloat k (sqrt ((scaleFloat mk x)^2 + (scaleFloat mk y)^2)) where k = max (exponent x) (exponent y) mk = - k phase :: (RealFloat a) => Complex a -> a phase (0 :+ 0) = 0 phase (x :+ y) = atan2 y x instance (RealFloat a) => Num (Complex a) where (x:+y) + (x':+y') = (x+x') :+ (y+y') (x:+y) - (x':+y') = (x-x') :+ (y-y') (x:+y) * (x':+y') = (x*x'-y*y') :+ (x*y'+y*x') negate (x:+y) = negate x :+ negate y abs z = magnitude z :+ 0 signum 0 = 0 signum z@(x:+y) = x/r :+ y/r where r = magnitude z fromInteger n = fromInteger n :+ 0 instance (RealFloat a) => Fractional (Complex a) where (x:+y) / (x':+y') = (x*x''+y*y'') / d :+ (y*x''-x*y'') / d where x'' = scaleFloat k x' y'' = scaleFloat k y' k = - max (exponent x') (exponent y') d = x'*x'' + y'*y'' fromRational a = fromRational a :+ 0 instance (RealFloat a) => Floating (Complex a) where pi = pi :+ 0 exp (x:+y) = expx * cos y :+ expx * sin y where expx = exp x log z = log (magnitude z) :+ phase z sqrt 0 = 0 sqrt z@(x:+y) = u :+ (if y < 0 then -v else v) where (u,v) = if x < 0 then (v',u') else (u',v') v' = abs y / (u'*2) u' = sqrt ((magnitude z + abs x) / 2) sin (x:+y) = sin x * cosh y :+ cos x * sinh y cos (x:+y) = cos x * cosh y :+ (- sin x * sinh y) tan (x:+y) = (sinx*coshy:+cosx*sinhy)/(cosx*coshy:+(-sinx*sinhy)) where sinx = sin x cosx = cos x sinhy = sinh y coshy = cosh y sinh (x:+y) = cos y * sinh x :+ sin y * cosh x cosh (x:+y) = cos y * cosh x :+ sin y * sinh x tanh (x:+y) = (cosy*sinhx:+siny*coshx)/(cosy*coshx:+siny*sinhx) where siny = sin y cosy = cos y sinhx = sinh x coshx = cosh x asin z@(x:+y) = y':+(-x') where (x':+y') = log (((-y):+x) + sqrt (1 - z*z)) acos z@(x:+y) = y'':+(-x'') where (x'':+y'') = log (z + ((-y'):+x')) (x':+y') = sqrt (1 - z*z) atan z@(x:+y) = y':+(-x') where (x':+y') = log (((1-y):+x) / sqrt (1+z*z)) asinh z = log (z + sqrt (1+z*z)) acosh z = log (z + (z+1) * sqrt ((z-1)/(z+1))) atanh z = log ((1+z) / sqrt (1-z*z)) haskell98-report-20080907/report/lib-code/Locale.hs0000644000175000017500000000240711345221573021170 0ustar marcotmarcotmodule Locale(TimeLocale(..), defaultTimeLocale) where data TimeLocale = TimeLocale { wDays :: [(String, String)], -- full and abbreviated week days months :: [(String, String)], -- full and abbreviated months amPm :: (String, String), -- AM/PM symbols dateTimeFmt, dateFmt, -- formatting strings timeFmt, time12Fmt :: String } deriving (Eq, Ord, Show) defaultTimeLocale :: TimeLocale defaultTimeLocale = TimeLocale { wDays = [("Sunday", "Sun"), ("Monday", "Mon"), ("Tuesday", "Tue"), ("Wednesday", "Wed"), ("Thursday", "Thu"), ("Friday", "Fri"), ("Saturday", "Sat")], months = [("January", "Jan"), ("February", "Feb"), ("March", "Mar"), ("April", "Apr"), ("May", "May"), ("June", "Jun"), ("July", "Jul"), ("August", "Aug"), ("September", "Sep"), ("October", "Oct"), ("November", "Nov"), ("December", "Dec")], amPm = ("AM", "PM"), dateTimeFmt = "%a %b %e %H:%M:%S %Z %Y", dateFmt = "%m/%d/%y", timeFmt = "%H:%M:%S", time12Fmt = "%I:%M:%S %p" } haskell98-report-20080907/report/lib-code/List.hs0000644000175000017500000002454611345221573020714 0ustar marcotmarcotmodule List ( elemIndex, elemIndices, find, findIndex, findIndices, nub, nubBy, delete, deleteBy, (\\), deleteFirstsBy, union, unionBy, intersect, intersectBy, intersperse, transpose, partition, group, groupBy, inits, tails, isPrefixOf, isSuffixOf, mapAccumL, mapAccumR, sort, sortBy, insert, insertBy, maximumBy, minimumBy, genericLength, genericTake, genericDrop, genericSplitAt, genericIndex, genericReplicate, zip4, zip5, zip6, zip7, zipWith4, zipWith5, zipWith6, zipWith7, 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, iterate, repeat, replicate, cycle, take, drop, splitAt, takeWhile, dropWhile, span, break, lines, words, unlines, unwords, reverse, and, or, any, all, elem, notElem, lookup, sum, product, maximum, minimum, concatMap, zip, zip3, zipWith, zipWith3, unzip, unzip3 ) where import Maybe( listToMaybe ) infix 5 \\ elemIndex :: Eq a => a -> [a] -> Maybe Int elemIndex x = findIndex (x ==) elemIndices :: Eq a => a -> [a] -> [Int] elemIndices x = findIndices (x ==) find :: (a -> Bool) -> [a] -> Maybe a find p = listToMaybe . filter p findIndex :: (a -> Bool) -> [a] -> Maybe Int findIndex p = listToMaybe . findIndices p findIndices :: (a -> Bool) -> [a] -> [Int] findIndices p xs = [ i | (x,i) <- zip xs [0..], p x ] nub :: Eq a => [a] -> [a] nub = nubBy (==) nubBy :: (a -> a -> Bool) -> [a] -> [a] nubBy eq [] = [] nubBy eq (x:xs) = x : nubBy eq (filter (\y -> not (eq x y)) xs) delete :: Eq a => a -> [a] -> [a] delete = deleteBy (==) deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a] deleteBy eq x [] = [] deleteBy eq x (y:ys) = if x `eq` y then ys else y : deleteBy eq x ys (\\) :: Eq a => [a] -> [a] -> [a] (\\) = foldl (flip delete) deleteFirstsBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] deleteFirstsBy eq = foldl (flip (deleteBy eq)) union :: Eq a => [a] -> [a] -> [a] union = unionBy (==) unionBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] unionBy eq xs ys = xs ++ deleteFirstsBy eq (nubBy eq ys) xs intersect :: Eq a => [a] -> [a] -> [a] intersect = intersectBy (==) intersectBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] intersectBy eq xs ys = [x | x <- xs, any (eq x) ys] intersperse :: a -> [a] -> [a] intersperse sep [] = [] 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' -- 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 transpose :: [[a]] -> [[a]] transpose [] = [] transpose ([] : xss) = transpose xss transpose ((x:xs) : xss) = (x : [h | (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) -- group splits its list argument into a list of lists of equal, adjacent -- elements. e.g., -- group "Mississippi" == ["M","i","ss","i","ss","i","pp","i"] group :: Eq a => [a] -> [[a]] group = groupBy (==) groupBy :: (a -> a -> Bool) -> [a] -> [[a]] groupBy eq [] = [] groupBy eq (x:xs) = (x:ys) : groupBy eq zs where (ys,zs) = span (eq x) xs -- inits xs returns the list of initial segments of xs, shortest first. -- e.g., inits "abc" == ["","a","ab","abc"] inits :: [a] -> [[a]] inits [] = [[]] inits (x:xs) = [[]] ++ map (x:) (inits xs) -- tails xs returns the list of all final segments of xs, longest first. -- e.g., tails "abc" == ["abc", "bc", "c",""] tails :: [a] -> [[a]] tails [] = [[]] tails xxs@(_:xs) = xxs : tails xs isPrefixOf :: Eq a => [a] -> [a] -> Bool isPrefixOf [] _ = True isPrefixOf _ [] = False isPrefixOf (x:xs) (y:ys) = x == y && isPrefixOf xs ys isSuffixOf :: Eq a => [a] -> [a] -> Bool isSuffixOf x y = reverse x `isPrefixOf` reverse y mapAccumL :: (a -> b -> (a, c)) -> a -> [b] -> (a, [c]) mapAccumL f s [] = (s, []) mapAccumL f s (x:xs) = (s'',y:ys) where (s', y ) = f s x (s'',ys) = mapAccumL f s' xs mapAccumR :: (a -> b -> (a, c)) -> a -> [b] -> (a, [c]) mapAccumR f s [] = (s, []) 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 sort :: (Ord a) => [a] -> [a] sort = sortBy compare sortBy :: (a -> a -> Ordering) -> [a] -> [a] sortBy cmp = foldr (insertBy cmp) [] insert :: (Ord a) => a -> [a] -> [a] insert = insertBy compare insertBy :: (a -> a -> Ordering) -> a -> [a] -> [a] insertBy cmp x [] = [x] insertBy cmp x ys@(y:ys') = case cmp x y of GT -> y : insertBy cmp x ys' _ -> x : 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 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 genericLength :: (Integral a) => [b] -> a genericLength [] = 0 genericLength (x:xs) = 1 + genericLength xs genericTake :: (Integral a) => a -> [b] -> [b] genericTake n _ | n <= 0 = [] genericTake _ [] = [] genericTake n (x:xs) = x : genericTake (n-1) xs genericDrop :: (Integral a) => a -> [b] -> [b] genericDrop n xs | n <= 0 = xs genericDrop _ [] = [] genericDrop n (_:xs) = genericDrop (n-1) xs genericSplitAt :: (Integral a) => a -> [b] -> ([b],[b]) genericSplitAt n xs | n <= 0 = ([],xs) genericSplitAt _ [] = ([],[]) genericSplitAt n (x:xs) = (x:xs',xs'') where (xs',xs'') = genericSplitAt (n-1) xs genericIndex :: (Integral a) => [b] -> a -> b genericIndex (x:_) 0 = x genericIndex (_:xs) n | n > 0 = genericIndex xs (n-1) | otherwise = error "List.genericIndex: negative argument" genericIndex _ _ = error "List.genericIndex: index too large" genericReplicate :: (Integral a) => a -> b -> [b] genericReplicate n x = genericTake n (repeat x) zip4 :: [a] -> [b] -> [c] -> [d] -> [(a,b,c,d)] zip4 = zipWith4 (,,,) zip5 :: [a] -> [b] -> [c] -> [d] -> [e] -> [(a,b,c,d,e)] zip5 = zipWith5 (,,,,) zip6 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [(a,b,c,d,e,f)] zip6 = zipWith6 (,,,,,) zip7 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g] -> [(a,b,c,d,e,f,g)] zip7 = zipWith7 (,,,,,,) zipWith4 :: (a->b->c->d->e) -> [a]->[b]->[c]->[d]->[e] zipWith4 z (a:as) (b:bs) (c:cs) (d:ds) = z a b c d : zipWith4 z as bs cs ds zipWith4 _ _ _ _ _ = [] zipWith5 :: (a->b->c->d->e->f) -> [a]->[b]->[c]->[d]->[e]->[f] zipWith5 z (a:as) (b:bs) (c:cs) (d:ds) (e:es) = z a b c d e : zipWith5 z as bs cs ds es zipWith5 _ _ _ _ _ _ = [] zipWith6 :: (a->b->c->d->e->f->g) -> [a]->[b]->[c]->[d]->[e]->[f]->[g] zipWith6 z (a:as) (b:bs) (c:cs) (d:ds) (e:es) (f:fs) = z a b c d e f : zipWith6 z as bs cs ds es fs zipWith6 _ _ _ _ _ _ _ = [] zipWith7 :: (a->b->c->d->e->f->g->h) -> [a]->[b]->[c]->[d]->[e]->[f]->[g]->[h] zipWith7 z (a:as) (b:bs) (c:cs) (d:ds) (e:es) (f:fs) (g:gs) = z a b c d e f g : zipWith7 z as bs cs ds es fs gs zipWith7 _ _ _ _ _ _ _ _ = [] unzip4 :: [(a,b,c,d)] -> ([a],[b],[c],[d]) unzip4 = foldr (\(a,b,c,d) ~(as,bs,cs,ds) -> (a:as,b:bs,c:cs,d:ds)) ([],[],[],[]) unzip5 :: [(a,b,c,d,e)] -> ([a],[b],[c],[d],[e]) unzip5 = foldr (\(a,b,c,d,e) ~(as,bs,cs,ds,es) -> (a:as,b:bs,c:cs,d:ds,e:es)) ([],[],[],[],[]) unzip6 :: [(a,b,c,d,e,f)] -> ([a],[b],[c],[d],[e],[f]) unzip6 = foldr (\(a,b,c,d,e,f) ~(as,bs,cs,ds,es,fs) -> (a:as,b:bs,c:cs,d:ds,e:es,f:fs)) ([],[],[],[],[],[]) unzip7 :: [(a,b,c,d,e,f,g)] -> ([a],[b],[c],[d],[e],[f],[g]) unzip7 = foldr (\(a,b,c,d,e,f,g) ~(as,bs,cs,ds,es,fs,gs) -> (a:as,b:bs,c:cs,d:ds,e:es,f:fs,g:gs)) ([],[],[],[],[],[],[]) haskell98-report-20080907/report/lib-code/IO.hs0000644000175000017500000000147411345221573020303 0ustar marcotmarcotmodule IO {- export list omitted -} where -- Just provide an implementation of the system-independent -- actions that IO exports. try :: IO a -> IO (Either IOError a) try f = catch (do r <- f return (Right r)) (return . Left) bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c bracket before after m = do x <- before rs <- try (m x) after x case rs of Right r -> return r Left e -> ioError e -- variant of the above where middle computation doesn't want x bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c bracket_ before after m = do x <- before rs <- try m after x case rs of Right r -> return r Left e -> ioError e haskell98-report-20080907/report/lib-code/Ix.hs0000644000175000017500000000256711345221573020360 0ustar marcotmarcotmodule Ix ( Ix(range, index, inRange, rangeSize) ) where class Ord a => Ix a where range :: (a,a) -> [a] index :: (a,a) -> a -> Int inRange :: (a,a) -> a -> Bool rangeSize :: (a,a) -> Int rangeSize b@(l,h) | null (range b) = 0 | otherwise = index b h + 1 -- NB: replacing "null (range b)" by "not (l <= h)" -- fails if the bounds are tuples. For example, -- (1,2) <= (2,1) -- but the range is nevertheless empty -- range ((1,2),(2,1)) = [] instance Ix Char where range (m,n) = [m..n] index b@(c,c') ci | inRange b ci = fromEnum ci - fromEnum c | otherwise = error "Ix.index: Index out of range." inRange (c,c') i = c <= i && i <= c' instance Ix Int where range (m,n) = [m..n] index b@(m,n) i | inRange b i = i - m | otherwise = error "Ix.index: Index out of range." inRange (m,n) i = m <= i && i <= n instance Ix Integer where range (m,n) = [m..n] index b@(m,n) i | inRange b i = fromInteger (i - m) | otherwise = error "Ix.index: Index out of range." inRange (m,n) i = m <= i && i <= n instance (Ix a,Ix b) => Ix (a, b) -- as derived, for all tuples instance Ix Bool -- as derived instance Ix Ordering -- as derived instance Ix () -- as derived haskell98-report-20080907/report/lib-code/Time.hs0000644000175000017500000001256711345221573020677 0ustar marcotmarcotmodule Time ( ClockTime, Month(January,February,March,April,May,June, July,August,September,October,November,December), Day(Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday), CalendarTime(CalendarTime, ctYear, ctMonth, ctDay, ctHour, ctMin, ctSec, ctPicosec, ctWDay, ctYDay, ctTZName, ctTZ, ctIsDST), TimeDiff(TimeDiff, tdYear, tdMonth, tdDay, tdHour, tdMin, tdSec, tdPicosec), getClockTime, addToClockTime, diffClockTimes, toCalendarTime, toUTCTime, toClockTime, calendarTimeToString, formatCalendarTime ) where import Ix(Ix) import Locale(TimeLocale(..),defaultTimeLocale) import Char ( intToDigit ) data ClockTime = ... -- Implementation-dependent instance Ord ClockTime where ... instance Eq ClockTime where ... data Month = January | February | March | April | May | June | July | August | September | October | November | December deriving (Eq, Ord, Enum, Bounded, Ix, Read, Show) data Day = Sunday | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday deriving (Eq, Ord, Enum, Bounded, Ix, Read, Show) data CalendarTime = CalendarTime { ctYear :: Int, ctMonth :: Month, ctDay, ctHour, ctMin, ctSec :: Int, ctPicosec :: Integer, ctWDay :: Day, ctYDay :: Int, ctTZName :: String, ctTZ :: Int, ctIsDST :: Bool } deriving (Eq, Ord, Read, Show) data TimeDiff = TimeDiff { tdYear, tdMonth, tdDay, tdHour, tdMin, tdSec :: Int, tdPicosec :: Integer } deriving (Eq, Ord, Read, Show) getClockTime :: IO ClockTime getClockTime = ... -- Implementation-dependent addToClockTime :: TimeDiff -> ClockTime -> ClockTime addToClockTime td ct = ... -- Implementation-dependent diffClockTimes :: ClockTime -> ClockTime -> TimeDiff diffClockTimes ct1 ct2 = ... -- Implementation-dependent toCalendarTime :: ClockTime -> IO CalendarTime toCalendarTime ct = ... -- Implementation-dependent toUTCTime :: ClockTime -> CalendarTime toUTCTime ct = ... -- Implementation-dependent toClockTime :: CalendarTime -> ClockTime toClockTime cal = ... -- Implementation-dependent calendarTimeToString :: CalendarTime -> String calendarTimeToString = formatCalendarTime defaultTimeLocale "%c" formatCalendarTime :: TimeLocale -> String -> CalendarTime -> String formatCalendarTime l fmt ct@(CalendarTime year mon day hour min sec sdec wday yday tzname _ _) = doFmt fmt where doFmt ('%':c:cs) = decode c ++ doFmt cs doFmt (c:cs) = c : doFmt cs doFmt "" = "" to12 :: Int -> Int to12 h = let h' = h `mod` 12 in if h' == 0 then 12 else h' decode 'A' = fst (wDays l !! fromEnum wday) decode 'a' = snd (wDays l !! fromEnum wday) decode 'B' = fst (months l !! fromEnum mon) decode 'b' = snd (months l !! fromEnum mon) decode 'h' = snd (months l !! fromEnum mon) decode 'C' = show2 (year `quot` 100) decode 'c' = doFmt (dateTimeFmt l) decode 'D' = doFmt "%m/%d/%y" decode 'd' = show2 day decode 'e' = show2' day decode 'H' = show2 hour decode 'I' = show2 (to12 hour) decode 'j' = show3 yday decode 'k' = show2' hour decode 'l' = show2' (to12 hour) decode 'M' = show2 min decode 'm' = show2 (fromEnum mon+1) decode 'n' = "\n" decode 'p' = (if hour < 12 then fst else snd) (amPm l) decode 'R' = doFmt "%H:%M" decode 'r' = doFmt (time12Fmt l) decode 'T' = doFmt "%H:%M:%S" decode 't' = "\t" decode 'S' = show2 sec decode 's' = ... -- Implementation-dependent decode 'U' = show2 ((yday + 7 - fromEnum wday) `div` 7) decode 'u' = show (let n = fromEnum wday in if n == 0 then 7 else n) decode 'V' = let (week, days) = (yday + 7 - if fromEnum wday > 0 then fromEnum wday - 1 else 6) `divMod` 7 in show2 (if days >= 4 then week+1 else if week == 0 then 53 else week) decode 'W' = show2 ((yday + 7 - if fromEnum wday > 0 then fromEnum wday - 1 else 6) `div` 7) decode 'w' = show (fromEnum wday) decode 'X' = doFmt (timeFmt l) decode 'x' = doFmt (dateFmt l) decode 'Y' = show year decode 'y' = show2 (year `rem` 100) decode 'Z' = tzname decode '%' = "%" decode c = [c] show2, show2', show3 :: Int -> String show2 x = [intToDigit (x `quot` 10), intToDigit (x `rem` 10)] show2' x = if x < 10 then [ ' ', intToDigit x] else show2 x show3 x = intToDigit (x `quot` 100) : show2 (x `rem` 100) haskell98-report-20080907/report/lib-code/Char.hs0000644000175000017500000001243411345221573020647 0ustar marcotmarcotmodule 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. import Numeric (readDec, readOct, lexDigits, readHex) import UnicodePrims -- Source of primitive Unicode functions. -- Character-testing operations isAscii, isLatin1, isControl, isPrint, isSpace, isUpper, isLower, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum :: Char -> Bool isAscii c = c < '\x80' isLatin1 c = c <= '\xff' isControl c = c < ' ' || c >= '\DEL' && c <= '\x9f' isPrint = primUnicodeIsPrint isSpace c = c `elem` " \t\n\r\f\v\xA0" -- Only Latin-1 spaces recognized isUpper = primUnicodeIsUpper -- 'A'..'Z' isLower = primUnicodeIsLower -- 'a'..'z' isAlpha c = isUpper c || isLower c isDigit c = c >= '0' && c <= '9' isOctDigit c = c >= '0' && c <= '7' isHexDigit c = isDigit c || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f' isAlphaNum = primUnicodeIsAlphaNum -- Digit conversion operations digitToInt :: Char -> Int digitToInt c | isDigit c = fromEnum c - fromEnum '0' | c >= 'a' && c <= 'f' = fromEnum c - fromEnum 'a' + 10 | c >= 'A' && c <= 'F' = fromEnum c - fromEnum 'A' + 10 | otherwise = error "Char.digitToInt: not a digit" intToDigit :: Int -> Char intToDigit i | i >= 0 && i <= 9 = toEnum (fromEnum '0' + i) | i >= 10 && i <= 15 = toEnum (fromEnum 'a' + i - 10) | otherwise = error "Char.intToDigit: not a digit" -- Case-changing operations toUpper :: Char -> Char toUpper = primUnicodeToUpper toLower :: Char -> Char toLower = primUnicodeToLower -- Character code functions ord :: Char -> Int ord = fromEnum chr :: Int -> Char chr = toEnum -- Text functions readLitChar :: ReadS Char readLitChar ('\\':s) = readEsc s readLitChar (c:s) = [(c,s)] readEsc :: ReadS Char readEsc ('a':s) = [('\a',s)] readEsc ('b':s) = [('\b',s)] readEsc ('f':s) = [('\f',s)] readEsc ('n':s) = [('\n',s)] readEsc ('r':s) = [('\r',s)] readEsc ('t':s) = [('\t',s)] readEsc ('v':s) = [('\v',s)] readEsc ('\\':s) = [('\\',s)] readEsc ('"':s) = [('"',s)] readEsc ('\'':s) = [('\'',s)] readEsc ('^':c:s) | c >= '@' && c <= '_' = [(chr (ord c - ord '@'), s)] readEsc s@(d:_) | isDigit d = [(chr n, t) | (n,t) <- readDec s] readEsc ('o':s) = [(chr n, t) | (n,t) <- readOct s] readEsc ('x':s) = [(chr n, t) | (n,t) <- readHex s] readEsc s@(c:_) | isUpper c = let table = ('\DEL', "DEL") : assocs asciiTab in case [(c,s') | (c, mne) <- table, ([],s') <- [match mne s]] of (pr:_) -> [pr] [] -> [] readEsc _ = [] match :: (Eq a) => [a] -> [a] -> ([a],[a]) match (x:xs) (y:ys) | x == y = match xs ys match xs ys = (xs,ys) showLitChar :: Char -> ShowS showLitChar c | c > '\DEL' = showChar '\\' . protectEsc isDigit (shows (ord c)) showLitChar '\DEL' = showString "\\DEL" showLitChar '\\' = showString "\\\\" showLitChar c | c >= ' ' = showChar c showLitChar '\a' = showString "\\a" showLitChar '\b' = showString "\\b" showLitChar '\f' = showString "\\f" showLitChar '\n' = showString "\\n" showLitChar '\r' = showString "\\r" showLitChar '\t' = showString "\\t" showLitChar '\v' = showString "\\v" showLitChar '\SO' = protectEsc (== 'H') (showString "\\SO") showLitChar c = showString ('\\' : asciiTab!c) protectEsc p f = f . cont where cont s@(c:_) | p c = "\\&" ++ s cont s = s asciiTab = listArray ('\NUL', ' ') ["NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US", "SP"] lexLitChar :: ReadS String lexLitChar ('\\':s) = map (prefix '\\') (lexEsc s) where lexEsc (c:s) | c `elem` "abfnrtv\\\"'" = [([c],s)] lexEsc ('^':c:s) | c >= '@' && c <= '_' = [(['^',c],s)] -- Numeric escapes lexEsc ('o':s) = [prefix 'o' (span isOctDigit s)] lexEsc ('x':s) = [prefix 'x' (span isHexDigit s)] lexEsc s@(d:_) | isDigit d = [span isDigit s] -- Very crude approximation to \XYZ. lexEsc s@(c:_) | isUpper c = [span isCharName s] lexEsc _ = [] isCharName c = isUpper c || isDigit c prefix c (t,s) = (c:t, s) lexLitChar (c:s) = [([c],s)] lexLitChar "" = [] haskell98-report-20080907/report/lib-code/Array.hs0000644000175000017500000000633111345221573021047 0ustar marcotmarcotmodule 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 // new_ivs = array (bounds a) (old_ivs ++ new_ivs) where old_ivs = [(i,a!i) | i <- indices a, i `notElem` new_is] new_is = [i | (i,_) <- new_ivs] 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 > arrPrec) ( showString "array " . showsPrec (arrPrec+1) (bounds a) . showChar ' ' . showsPrec (arrPrec+1) (assocs a) ) instance (Ix a, Read a, Read b) => Read (Array a b) where readsPrec p = readParen (p > arrPrec) (\r -> [ (array b as, u) | ("array",s) <- lex r, (b,t) <- readsPrec (arrPrec+1) s, (as,u) <- readsPrec (arrPrec+1) t ]) -- Precedence of the 'array' function is that of application itself arrPrec = 10 haskell98-report-20080907/report/classes.eps0000644000175000017500000013350711345221573020133 0ustar marcotmarcot%!PS-Adobe-3.0 EPSF-3.0 %%Title: Microsoft PowerPoint - classes.ppt %%Creator: PScript5.dll Version 5.2 %%CreationDate: 4/22/2002 16:28:25 %%BoundingBox: 95 150 503 680 %%Pages: 1 %%Orientation: Portrait %%PageOrder: Ascend %%DocumentNeededResources: (atend) %%DocumentSuppliedResources: (atend) %%DocumentData: Clean7Bit %%TargetDevice: (Xerox Document Centre 432/440ST) (3010.106) 2200 %%LanguageLevel: 3 %%EndComments %%BeginDefaults %%PageBoundingBox: 12 12 583 830 %%ViewingOrientation: 1 0 0 1 %%EndDefaults %%BeginProlog %%BeginResource: file Pscript_WinNT_ErrorHandler 5.0 0 /currentpacking where{pop/oldpack currentpacking def/setpacking where{pop false setpacking}if}if/$brkpage 64 dict def $brkpage begin/prnt{dup type/stringtype ne{=string cvs}if dup length 6 mul/tx exch def/ty 10 def currentpoint/toy exch def/tox exch def 1 setgray newpath tox toy 2 sub moveto 0 ty rlineto tx 0 rlineto 0 ty neg rlineto closepath fill tox toy moveto 0 setgray show}bind def /nl{currentpoint exch pop lmargin exch moveto 0 -10 rmoveto}def/=={/cp 0 def typeprint nl}def/typeprint{dup type exec}readonly def/lmargin 72 def/rmargin 72 def/tprint{dup length cp add rmargin gt{nl/cp 0 def}if dup length cp add/cp exch def prnt}readonly def/cvsprint{=string cvs tprint( )tprint}readonly def /integertype{cvsprint}readonly def/realtype{cvsprint}readonly def/booleantype {cvsprint}readonly def/operatortype{(--)tprint =string cvs tprint(-- )tprint} readonly def/marktype{pop(-mark- )tprint}readonly def/dicttype{pop (-dictionary- )tprint}readonly def/nulltype{pop(-null- )tprint}readonly def /filetype{pop(-filestream- )tprint}readonly def/savetype{pop(-savelevel- ) tprint}readonly def/fonttype{pop(-fontid- )tprint}readonly def/nametype{dup xcheck not{(/)tprint}if cvsprint}readonly def/stringtype{dup rcheck{(\()tprint tprint(\))tprint}{pop(-string- )tprint}ifelse}readonly def/arraytype{dup rcheck {dup xcheck{({)tprint{typeprint}forall(})tprint}{([)tprint{typeprint}forall(]) tprint}ifelse}{pop(-array- )tprint}ifelse}readonly def/packedarraytype{dup rcheck{dup xcheck{({)tprint{typeprint}forall(})tprint}{([)tprint{typeprint} forall(])tprint}ifelse}{pop(-packedarray- )tprint}ifelse}readonly def/courier /Courier findfont 10 scalefont def end errordict/handleerror{systemdict begin $error begin $brkpage begin newerror{/newerror false store vmstatus pop pop 0 ne{grestoreall}if errorname(VMerror)ne{showpage}if initgraphics courier setfont lmargin 720 moveto errorname(VMerror)eq{userdict/ehsave known{clear userdict /ehsave get restore 2 vmreclaim}if vmstatus exch pop exch pop PrtVMMsg}{ (ERROR: )prnt errorname prnt nl(OFFENDING COMMAND: )prnt/command load prnt $error/ostack known{nl nl(STACK:)prnt nl nl $error/ostack get aload length{==} repeat}if}ifelse systemdict/showpage get exec(%%[ Error: )print errorname =print(; OffendingCommand: )print/command load =print( ]%%)= flush}if end end end}dup 0 systemdict put dup 4 $brkpage put bind readonly put/currentpacking where{pop/setpacking where{pop oldpack setpacking}if}if %%EndResource userdict /Pscript_WinNT_Incr 230 dict dup begin put %%BeginResource: file Pscript_FatalError 5.0 0 userdict begin/FatalErrorIf{{initgraphics findfont 1 index 0 eq{exch pop}{dup length dict begin{1 index/FID ne{def}{pop pop}ifelse}forall/Encoding {ISOLatin1Encoding}stopped{StandardEncoding}if def currentdict end /ErrFont-Latin1 exch definefont}ifelse exch scalefont setfont counttomark 3 div cvi{moveto show}repeat showpage quit}{cleartomark}ifelse}bind def end %%EndResource userdict begin/PrtVMMsg{vmstatus exch sub exch pop gt{[ (This job requires more memory than is available in this printer.)100 500 (Try one or more of the following, and then print again:)100 485 (For the output format, choose Optimize For Portability.)115 470 (In the Device Settings page, make sure the Available PostScript Memory is accurate.) 115 455(Reduce the number of fonts in the document.)115 440 (Print the document in parts.)115 425 12/Times-Roman showpage (%%[ PrinterError: Low Printer VM ]%%)= true FatalErrorIf}if}bind def end version cvi 2016 ge{/VM?{pop}bind def}{/VM? userdict/PrtVMMsg get def}ifelse %%BeginResource: file Pscript_Win_Basic 5.0 0 /d/def load def/,/load load d/~/exch , d/?/ifelse , d/!/pop , d/`/begin , d/^ /index , d/@/dup , d/+/translate , d/$/roll , d/U/userdict , d/M/moveto , d/- /rlineto , d/&/currentdict , d/:/gsave , d/;/grestore , d/F/false , d/T/true , d/N/newpath , d/E/end , d/Ac/arc , d/An/arcn , d/A/ashow , d/D/awidthshow , d/C /closepath , d/V/div , d/O/eofill , d/L/fill , d/I/lineto , d/-c/curveto , d/-M /rmoveto , d/+S/scale , d/Ji/setfont , d/Lc/setlinecap , d/Lj/setlinejoin , d /Lw/setlinewidth , d/Lm/setmiterlimit , d/sd/setdash , d/S/show , d/LH/showpage , d/K/stroke , d/W/widthshow , d/R/rotate , d/L2? false/languagelevel where{pop languagelevel 2 ge{pop true}if}if d L2?{/xS/xshow , d/yS/yshow , d/zS/xyshow , d}if/b{bind d}bind d/bd{bind d}bind d/xd{~ d}bd/ld{, d}bd/bn/bind ld/lw/Lw ld /lc/Lc ld/lj/Lj ld/sg/setgray ld/ADO_mxRot null d/self & d/OrgMx matrix currentmatrix d/reinitialize{: OrgMx setmatrix[/TextInit/GraphInit/UtilsInit counttomark{@ where{self eq}{F}?{cvx exec}{!}?}repeat cleartomark ;}b /initialize{`{/Pscript_Win_Data where{!}{U/Pscript_Win_Data & put}?/ADO_mxRot ~ d/TextInitialised? F d reinitialize E}{U/Pscript_Win_Data 230 dict @ ` put /ADO_mxRot ~ d/TextInitialised? F d reinitialize}?}b/terminate{!{& self eq {exit}{E}?}loop E}b/suspend/terminate , d/resume{` Pscript_Win_Data `}b U ` /lucas 21690 d/featurebegin{countdictstack lucas[}b/featurecleanup{stopped {cleartomark @ lucas eq{! exit}if}loop countdictstack ~ sub @ 0 gt{{E}repeat} {!}?}b E/snap{transform 0.25 sub round 0.25 add ~ 0.25 sub round 0.25 add ~ itransform}b/dsnap{dtransform round ~ round ~ idtransform}b/nonzero_round{@ 0.5 ge{round}{@ -0.5 lt{round}{0 ge{1}{-1}?}?}?}b/nonzero_dsnap{dtransform nonzero_round ~ nonzero_round ~ idtransform}b U<04>cvn{}put/rr{1 ^ 0 - 0 ~ - neg 0 - C}b/irp{4 -2 $ + +S fx 4 2 $ M 1 ^ 0 - 0 ~ - neg 0 -}b/rp{4 2 $ M 1 ^ 0 - 0 ~ - neg 0 -}b/solid{[]0 sd}b/g{@ not{U/DefIf_save save put}if U/DefIf_bool 2 ^ put}b/DefIf_El{if U/DefIf_bool get not @{U/DefIf_save get restore}if}b/e {DefIf_El !}b/UDF{L2?{undefinefont}{!}?}b/UDR{L2?{undefineresource}{! !}?}b /freeVM{/Courier findfont[40 0 0 -40 0 0]makefont Ji 2 vmreclaim}b/hfRedefFont {findfont @ length dict `{1 ^/FID ne{d}{! !}?}forall & E @ ` ~{/CharStrings 1 dict `/.notdef 0 d & E d}if/Encoding 256 array 0 1 255{1 ^ ~/.notdef put}for d E definefont !}bind d/hfMkCIDFont{/CIDFont findresource @ length 2 add dict `{1 ^ @/FID eq ~ @/XUID eq ~/UIDBase eq or or{! !}{d}?}forall/CDevProc ~ d/Metrics2 16 dict d/CIDFontName 1 ^ d & E 1 ^ ~/CIDFont defineresource ![~]composefont !} bind d %%EndResource %%BeginResource: file Pscript_Win_Utils_L2 5.0 0 /rf/rectfill , d/fx{1 1 dtransform @ 0 ge{1 sub 0.5}{1 add -0.5}? 3 -1 $ @ 0 ge {1 sub 0.5}{1 add -0.5}? 3 1 $ 4 1 $ idtransform 4 -2 $ idtransform}b/BZ{4 -2 $ snap + +S fx rf}b/rs/rectstroke , d/rc/rectclip , d/UtilsInit{currentglobal{F setglobal}if}b/scol{! setcolor}b/colspA/DeviceGray d/colspABC/DeviceRGB d /colspRefresh{colspABC setcolorspace}b/SetColSpace{colspABC setcolorspace}b /resourcestatus where{!/ColorRendering/ProcSet resourcestatus{! ! T}{F}?}{F}? not{/ColorRendering<>/defineresource where{!/ProcSet defineresource !}{! !}?}if/buildcrdname{/ColorRendering/ProcSet findresource ` mark GetHalftoneName @ type @/nametype ne ~/stringtype ne and{!/none}if(.) GetPageDeviceName @ type @/nametype ne ~/stringtype ne and{!/none}if(.)5 ^ 0 5 -1 1{^ length add}for string 6 1 $ 5 ^ 5{~ 1 ^ cvs length 1 ^ length 1 ^ sub getinterval}repeat ! cvn 3 1 $ ! ! E}b/definecolorrendering{~ buildcrdname ~ /ColorRendering defineresource !}b/findcolorrendering where{!}{ /findcolorrendering{buildcrdname @/ColorRendering resourcestatus{! ! T}{ /ColorRendering/ProcSet findresource ` GetSubstituteCRD E F}?}b}? /selectcolorrendering{findcolorrendering !/ColorRendering findresource setcolorrendering}b/G2UBegin{findresource/FontInfo get/GlyphNames2Unicode get `}bind d/G2CCBegin{findresource/FontInfo get/GlyphNames2HostCode get `}bind d /G2UEnd{E}bind d/AddFontInfoBegin{/FontInfo 8 dict @ `}bind d/AddFontInfo{ /GlyphNames2Unicode 16 dict d/GlyphNames2HostCode 16 dict d}bind d /AddFontInfoEnd{E d}bind d/T0AddCFFMtx2{/CIDFont findresource/Metrics2 get ` d E}bind d %%EndResource end %%EndProlog %%BeginSetup [ 1 0 0 1 0 0 ] false Pscript_WinNT_Incr dup /initialize get exec 1 setlinecap 1 setlinejoin /mysetup [ 72 600 V 0 0 -72 600 V 11.99905 830.00128 ] def %%EndSetup %%Page: 1 1 %%PageBoundingBox: 12 12 583 830 %%EndPageComments %%BeginPageSetup /DeviceRGB dup setcolorspace /colspABC exch def mysetup concat colspRefresh %%EndPageSetup Pscript_WinNT_Incr begin %%BeginResource: file Pscript_WinNT_Compat 5.0 0 userdict/Pscript_WinNT_Compat 19 dict dup begin/bd{bind def}bind def/ld{load def}bd/$x matrix def/ANSIVec[16#0/grave 16#1/acute 16#2/circumflex 16#3/tilde 16#4/macron 16#5/breve 16#6/dotaccent 16#7/dieresis 16#8/ring 16#9/cedilla 16#A /hungarumlaut 16#B/ogonek 16#C/caron 16#D/dotlessi 16#27/quotesingle 16#60 /grave 16#7C/bar 16#82/quotesinglbase 16#83/florin 16#84/quotedblbase 16#85 /ellipsis 16#86/dagger 16#87/daggerdbl 16#88/circumflex 16#89/perthousand 16#8A /Scaron 16#8B/guilsinglleft 16#8C/OE 16#91/quoteleft 16#92/quoteright 16#93 /quotedblleft 16#94/quotedblright 16#95/bullet 16#96/endash 16#97/emdash 16#98 /tilde 16#99/trademark 16#9A/scaron 16#9B/guilsinglright 16#9C/oe 16#9F /Ydieresis 16#A0/space 16#A1/exclamdown 16#A4/currency 16#A5/yen 16#A6 /brokenbar 16#A7/section 16#A8/dieresis 16#A9/copyright 16#AA/ordfeminine 16#AB /guillemotleft 16#AC/logicalnot 16#AD/hyphen 16#AE/registered 16#AF/macron 16#B0/degree 16#B1/plusminus 16#B2/twosuperior 16#B3/threesuperior 16#B4/acute 16#B5/mu 16#B6/paragraph 16#B7/periodcentered 16#B8/cedilla 16#B9/onesuperior 16#BA/ordmasculine 16#BB/guillemotright 16#BC/onequarter 16#BD/onehalf 16#BE /threequarters 16#BF/questiondown 16#C0/Agrave 16#C1/Aacute 16#C2/Acircumflex 16#C3/Atilde 16#C4/Adieresis 16#C5/Aring 16#C6/AE 16#C7/Ccedilla 16#C8/Egrave 16#C9/Eacute 16#CA/Ecircumflex 16#CB/Edieresis 16#CC/Igrave 16#CD/Iacute 16#CE /Icircumflex 16#CF/Idieresis 16#D0/Eth 16#D1/Ntilde 16#D2/Ograve 16#D3/Oacute 16#D4/Ocircumflex 16#D5/Otilde 16#D6/Odieresis 16#D7/multiply 16#D8/Oslash 16#D9/Ugrave 16#DA/Uacute 16#DB/Ucircumflex 16#DC/Udieresis 16#DD/Yacute 16#DE /Thorn 16#DF/germandbls 16#E0/agrave 16#E1/aacute 16#E2/acircumflex 16#E3 /atilde 16#E4/adieresis 16#E5/aring 16#E6/ae 16#E7/ccedilla 16#E8/egrave 16#E9 /eacute 16#EA/ecircumflex 16#EB/edieresis 16#EC/igrave 16#ED/iacute 16#EE /icircumflex 16#EF/idieresis 16#F0/eth 16#F1/ntilde 16#F2/ograve 16#F3/oacute 16#F4/ocircumflex 16#F5/otilde 16#F6/odieresis 16#F7/divide 16#F8/oslash 16#F9 /ugrave 16#FA/uacute 16#FB/ucircumflex 16#FC/udieresis 16#FD/yacute 16#FE/thorn 16#FF/ydieresis]def currentdict{dup type/operatortype eq{[exch]cvx def}{pop pop}ifelse}forall/initialize{currentdict exch begin begin}bind def/terminate{ /@FL where not{pop end end}{pop}ifelse}bind def/suspend/terminate load def /resume/initialize load def/RS{/pagesave where{pop pagesave restore}{$x matrix invertmatrix concat}ifelse}def/SS{/pagesave save def}def/CB{pop pop pop pop}def /B{pop pop pop pop}def/:/gsave load def/;/grestore load def/N/newpath load def end put %%EndResource end reinitialize Pscript_WinNT_Compat begin /$x mysetup def end Pscript_WinNT_Incr dup /suspend get exec Pscript_WinNT_Compat dup /initialize get exec %%BeginDocument: Pscript_Win_PassThrough userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 0 GpPBeg NP 519 1008 m 4239 1008 l 4239 5808 l 519 5808 l CP eoclip 1 1 1 SC NP 518 1007 m 4238 1007 l 4238 5808 l 518 5808 l CP AF GSE userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 1 1 10 8.3333 [] 0 1 GpPBeg 0.0039 0.0039 0.0039 SC NP 1348 1377 m 1095 1377 890 1483 890 1614 c 890 1745 1095 1851 1348 1851 c 1600 1851 1805 1745 1805 1614 c 1805 1483 1600 1377 1348 1377 c CP S GSE %%EndDocument Pscript_WinNT_Compat dup /suspend get exec Pscript_WinNT_Incr dup /resume get exec /DeviceRGB dup setcolorspace /colspABC exch def 0 0 0 1 scol Pscript_WinNT_Incr begin %%BeginResource: file Pscript_Text 5.0 0 /TextInit{TextInitialised? not{/Pscript_Windows_Font & d/TextInitialised? T d /fM[1 0 0 1 0 0]d/mFM matrix d/iMat[1 0 0.212557 1 0 0]d}if}b/copyfont{1 ^ length add dict `{1 ^/FID ne{d}{! !}?}forall & E}b/EncodeDict 11 dict d/bullets {{/bullet}repeat}b/rF{3 copyfont @ ` ~ EncodeDict ~ get/Encoding ~ 3 ^/0 eq{& /CharStrings known{CharStrings/Eth known not{! EncodeDict/ANSIEncodingOld get} if}if}if d E}b/mF{@ 7 1 $ findfont ~{@/Encoding get @ StandardEncoding eq{! T}{ {ISOLatin1Encoding}stopped{! F}{eq}?{T}{@ ` T 32 1 127{Encoding 1 ^ get StandardEncoding 3 -1 $ get eq and}for E}?}?}{F}?{1 ^ ~ rF}{0 copyfont}? 6 -2 $ ! ! ~ !/pd_charset @ where{~ get 128 eq{@ FDV 2 copy get @ length array copy put pd_CoverFCRange}if}{!}? 2 ^ ~ definefont fM 5 4 -1 $ put fM 4 0 put fM makefont Pscript_Windows_Font 3 1 $ put}b/sLT{: Lw -M currentpoint snap M 0 - 0 Lc K ;}b/xUP null d/yUP null d/uW null d/xSP null d/ySP null d/sW null d/sSU{N /uW ~ d/yUP ~ d/xUP ~ d}b/sU{xUP yUP uW sLT}b/sST{N/sW ~ d/ySP ~ d/xSP ~ d}b/sT {xSP ySP sW sLT}b/sR{: + R 0 0 M}b/sRxy{: matrix astore concat 0 0 M}b/eR/; , d /AddOrigFP{{&/FontInfo known{&/FontInfo get length 6 add}{6}? dict ` /WinPitchAndFamily ~ d/WinCharSet ~ d/OrigFontType ~ d/OrigFontStyle ~ d /OrigFontName ~ d & E/FontInfo ~ d}{! ! ! ! !}?}b/mFS{makefont Pscript_Windows_Font 3 1 $ put}b/mF42D{0 copyfont `/FontName ~ d 2 copy ~ sub 1 add dict `/.notdef 0 d 2 copy 1 ~{@ 3 ^ sub Encoding ~ get ~ d}for & E /CharStrings ~ d ! ! & @ E/FontName get ~ definefont}b/mF42{15 dict ` @ 4 1 $ FontName ~ d/FontType 0 d/FMapType 2 d/FontMatrix[1 0 0 1 0 0]d 1 ^ 254 add 255 idiv @ array/Encoding ~ d 0 1 3 -1 $ 1 sub{@ Encoding 3 1 $ put}for/FDepVector Encoding length array d/CharStrings 2 dict `/.notdef 0 d & E d 0 1 Encoding length 1 sub{@ @ 10 lt{! FontName length 1 add string}{100 lt{FontName length 2 add string}{FontName length 3 add string}?}? @ 0 FontName @ length string cvs putinterval @ 3 -1 $ @ 4 1 $ 3 string cvs FontName length ~ putinterval cvn 1 ^ 256 mul @ 255 add 3 -1 $ 4 ^ findfont mF42D FDepVector 3 1 $ put}for & @ E /FontName get ~ definefont ! ! ! mF}b/mF_OTF_V{~ ! ~ ! 4 -1 $ ! findfont 2 ^ ~ definefont fM @ @ 4 6 -1 $ neg put 5 0 put 90 matrix R matrix concatmatrix makefont Pscript_Windows_Font 3 1 $ put}b/mF_TTF_V{3{~ !}repeat 3 -1 $ ! findfont 1 ^ ~ definefont Pscript_Windows_Font 3 1 $ put}b/UmF{L2? {Pscript_Windows_Font ~ undef}{!}?}b/UmF42{@ findfont/FDepVector get{/FontName get undefinefont}forall undefinefont}b %%EndResource end reinitialize Pscript_WinNT_Incr begin %%BeginResource: file Pscript_Encoding256 5.0 0 /CharCol256Encoding[/.notdef/breve/caron/dotaccent/dotlessi/fi/fl/fraction /hungarumlaut/Lslash/lslash/minus/ogonek/ring/Zcaron/zcaron/.notdef/.notdef /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef /.notdef/.notdef/.notdef/.notdef/.notdef/space/exclam/quotedbl/numbersign /dollar/percent/ampersand/quotesingle/parenleft/parenright/asterisk/plus/comma /hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon /semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S /T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore/grave /a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright /asciitilde/.notdef/Euro/.notdef/quotesinglbase/florin/quotedblbase/ellipsis /dagger/daggerdbl/circumflex/perthousand/Scaron/guilsinglleft/OE/.notdef /.notdef/.notdef/.notdef/quoteleft/quoteright/quotedblleft/quotedblright/bullet /endash/emdash/tilde/trademark/scaron/guilsinglright/oe/.notdef/.notdef /Ydieresis/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar/section /dieresis/copyright/ordfeminine/guillemotleft/logicalnot/.notdef/registered /macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph /periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter /onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis /Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute /Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis /multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls /agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute /ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve /oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex /udieresis/yacute/thorn/ydieresis]def EncodeDict/256 CharCol256Encoding put %%EndResource end reinitialize %%IncludeResource: font Courier-Bold Pscript_WinNT_Incr begin %%BeginResource: file Pscript_Win_Euro_L2 5.0 0 /UseT3EuroFont{/currentdistillerparams where{pop currentdistillerparams /CoreDistVersion get 4000 le}{false}ifelse}bind def/NewEuroT3Font?{dup/FontType get 3 eq{dup/EuroFont known exch/BaseFont known and}{pop false}ifelse}bind def /T1FontHasEuro{dup/CharStrings known not{dup NewEuroT3Font?{dup/EuroGlyphName get exch/EuroFont get/CharStrings get exch known{true}{false}ifelse}{pop false} ifelse}{dup/FontType get 1 eq{/CharStrings get/Euro known}{dup/InfoDict known{ /InfoDict get/Euro known}{/CharStrings get/Euro known}ifelse}ifelse}ifelse}bind def/FontHasEuro{findfont dup/Blend known{pop true}{T1FontHasEuro}ifelse}bind def/EuroEncodingIdx 1 def/EuroFontHdr{12 dict begin/FontInfo 10 dict dup begin /version(001.000)readonly def/Notice(Copyright (c)1999 Adobe Systems Incorporated. All Rights Reserved.)readonly def/FullName(Euro)readonly def /FamilyName(Euro)readonly def/Weight(Regular)readonly def/isFixedPitch false def/ItalicAngle 0 def/UnderlinePosition -100 def/UnderlineThickness 50 def end readonly def/FontName/Euro def/Encoding 256 array 0 1 255{1 index exch/.notdef put}for def/PaintType 0 def/FontType 1 def/FontMatrix[0.001 0 0 0.001 0 0]def /FontBBox{-25 -23 1500 804}readonly def currentdict end dup/Private 20 dict dup begin/ND{def}def/NP{put}def/lenIV -1 def/RD{string currentfile exch readhexstring pop}def/-|{string currentfile exch readstring pop}executeonly def /|-{def}executeonly def/|{put}executeonly def/BlueValues[-20 0 706 736 547 572] |-/OtherBlues[-211 -203]|-/BlueScale 0.0312917 def/MinFeature{16 16}|-/StdHW [60]|-/StdVW[71]|-/ForceBold false def/password 5839 def/Erode{8.5 dup 3 -1 roll 0.1 mul exch 0.5 sub mul cvi sub dup mul 71 0 dtransform dup mul exch dup mul add le{pop pop 1.0 1.0}{pop pop 0.0 1.5}ifelse}def/OtherSubrs[{}{}{} {systemdict/internaldict known not{pop 3}{1183615869 systemdict/internaldict get exec dup/startlock known{/startlock get exec}{dup/strtlck known{/strtlck get exec}{pop 3}ifelse}ifelse}ifelse}executeonly]|-/Subrs 5 array dup 0 <8E8B0C100C110C110C210B>put dup 1<8B8C0C100B>put dup 2<8B8D0C100B>put dup 3<0B> put dup 4<8E8C8E0C100C110A0B>put |- 2 index/CharStrings 256 dict dup begin /.notdef<8b8b0d0e>def end end put put dup/FontName get exch definefont pop}bind def/AddEuroGlyph{2 index exch EuroEncodingIdx 1 eq{EuroFontHdr}if systemdict begin/Euro findfont dup dup/Encoding get 5 1 roll/Private get begin/CharStrings get dup 3 index known{pop pop pop pop end end}{begin 1 index exch def end end end EuroEncodingIdx dup 1 add/EuroEncodingIdx exch def exch put}ifelse}bind def /GetNewXUID{currentdict/XUID known{[7 XUID aload pop]true}{currentdict/UniqueID known{[7 UniqueID]true}{false}ifelse}ifelse}bind def/BuildT3EuroFont{exch 16 dict begin dup/FontName exch def findfont dup/Encoding get/Encoding exch def dup length 1 add dict copy dup/FID undef begin dup dup/FontName exch def /Encoding 256 array 0 1 255{1 index exch/.notdef put}for def GetNewXUID{/XUID exch def}if currentdict end definefont pop/BaseFont exch findfont 1000 scalefont def/EuroFont exch findfont 1000 scalefont def pop/EuroGlyphName exch def/FontType 3 def/FontMatrix[.001 0 0 .001 0 0]def/FontBBox BaseFont/FontBBox get def/Char 1 string def/BuildChar{exch dup begin/Encoding get 1 index get /Euro eq{BaseFont T1FontHasEuro{false}{true}ifelse}{false}ifelse{EuroFont setfont pop userdict/Idx 0 put EuroFont/Encoding get{EuroGlyphName eq{exit} {userdict/Idx Idx 1 add put}ifelse}forall userdict/Idx get}{dup dup Encoding exch get BaseFont/Encoding get 3 1 roll put BaseFont setfont}ifelse Char 0 3 -1 roll put Char stringwidth newpath 0 0 moveto Char true charpath flattenpath pathbbox setcachedevice 0 0 moveto Char show end}bind def currentdict end dup /FontName get exch definefont pop}bind def/AddEuroToT1Font{dup findfont dup length 10 add dict copy dup/FID undef begin/EuroFont 3 -1 roll findfont 1000 scalefont def CharStrings dup length 1 add dict copy begin/Euro{EuroFont setfont pop EuroGBBox aload pop setcachedevice 0 0 moveto EuroGName glyphshow} bind def currentdict end/CharStrings exch def GetNewXUID{/XUID exch def}if 3 1 roll/EuroGBBox exch def/EuroGName exch def currentdict end definefont pop}bind def/BuildNewFont{UseT3EuroFont{BuildT3EuroFont}{pop AddEuroToT1Font}ifelse}bind def/UseObliqueEuro{findfont/FontMatrix get dup 2 get 0 eq exch dup 0 get exch 3 get eq and UseT3EuroFont or}bind def %%EndResource end reinitialize /Courier-Bold FontHasEuro not { /Euro.Courier-Bold [600 0 6 -12 585 612 ] <91F8EC0DDBE803F875E7037FE701F755DC01F7D7DC01F8C47701F80FF7A615FB61068A94 8B958B95088B928B918C9208F76E06A4DC05FB76068F0ADBE803F875E7037FE701F755DC 01F7D7DC01F89CE701A1D4C1B6DF8B08BF8BC46DA067084A07E706F773072F068F0ADBE8 03F875E7037FE701F755DC01F7D7DC01F8C4770157078F0ADBE803F875E7037FE701F755 DC01F7D7DC01F89CE70165AE549C5E8B08FB138B2F386BFB11084806723A05DB0678078B 818B818C81085306723A05E806A9FB08DD32F7288B08B28BF7039FD7D00853CF056B754E 603B8B08448B51B56ED208F73606090E> AddEuroGlyph /Euro /Courier-Bold /Courier-Bold-Copy BuildNewFont } if F /F0 0 /256 T /Courier-Bold mF /F0S85 F0 [133 0 0 -133 0 0 ] mFS F0S85 Ji 1267 1594 M (Eq)[80 0]xS %%IncludeResource: font TimesNewRomanPSMT /TimesNewRomanPSMT FontHasEuro not { /Euro.TimesNewRomanPSMT [500 0 -10 -12 482 676 ] <80F8880DBAEF03F8629E037FB401F7ADB101F7FCB101F918AB01F83DF7FC1596B105FBB5 0695EAB0F72BF70D8B08EE8BB34A932F089E06F7260757A6539B518B088F0ABCEA03F862 9E037FB401F7ADB101F7FCB101F918AB01FB328B36FB1C77FB22086206806505BB068A7D 8B7E8B7D086706806505BC0696FB1FC5FB2EF7388B08F58BC0C5BFDE087C95055B486460 328B08FB0C8B68F73288E908F7950696B105FBA1068CB405090E> AddEuroGlyph /Euro /TimesNewRomanPSMT /TimesNewRomanPSMT-Copy BuildNewFont } if F /F1 0 /256 T /TimesNewRomanPSMT mF /F1S64 F1 [100 0 0 -100 0 0 ] mFS F1S64 Ji 972 1730 M (All except IO, \()[72 28 28 25 44 51 44 44 51 28 26 32 72 25 25 0]xS 1600 1730 M (-)S 1634 1730 M (>\))[56 0]xS Pscript_WinNT_Compat begin /$x mysetup def end Pscript_WinNT_Incr dup /suspend get exec Pscript_WinNT_Compat dup /initialize get exec %%BeginDocument: Pscript_Win_PassThrough userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 1 1 10 8.3333 [] 0 1 GpPBeg 0.0039 0.0039 0.0039 SC NP 1370 2043 m 1105 2043 890 2152 890 2285 c 890 2419 1105 2527 1370 2527 c 1635 2527 1850 2419 1850 2285 c 1850 2152 1635 2043 1370 2043 c CP S GSE %%EndDocument Pscript_WinNT_Compat dup /suspend get exec Pscript_WinNT_Incr dup /resume get exec /DeviceRGB dup setcolorspace /colspABC exch def 0 0 0 1 scol F0S85 Ji 1249 2206 M (Ord)[80 80 0]xS F1S64 Ji 1072 2341 M (All except \()[72 28 28 25 44 51 44 44 51 28 25 0]xS 1545 2341 M (-)S 1579 2341 M (>\))[56 0]xS 1121 2461 M (IO, )[32 72 25 25 0]xS 1302 2461 M (IOError)[31 73 61 34 33 50 0]xS Pscript_WinNT_Compat begin /$x mysetup def end Pscript_WinNT_Incr dup /suspend get exec Pscript_WinNT_Compat dup /initialize get exec %%BeginDocument: Pscript_Win_PassThrough userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 1 1 10 8.3333 [] 0 1 GpPBeg 0.0039 0.0039 0.0039 SC NP 2456 2045 m 2190 2045 1974 2153 1974 2286 c 1974 2418 2190 2526 2456 2526 c 2723 2526 2939 2418 2939 2286 c 2939 2153 2723 2045 2456 2045 c CP S GSE %%EndDocument Pscript_WinNT_Compat dup /suspend get exec Pscript_WinNT_Incr dup /resume get exec /DeviceRGB dup setcolorspace /colspABC exch def 0 0 0 1 scol F0S85 Ji 2336 2207 M (Num)[80 80 0]xS F1S64 Ji 2209 2342 M (Int)[32 50 0]xS 2319 2342 M (, Integer, )[25 27 32 50 29 45 49 45 33 25 0]xS 2180 2462 M (Float, Double)[55 28 50 44 28 25 25 72 50 50 50 29 0]xS Pscript_WinNT_Compat begin /$x mysetup def end Pscript_WinNT_Incr dup /suspend get exec Pscript_WinNT_Compat dup /initialize get exec %%BeginDocument: Pscript_Win_PassThrough userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 0 GpPBeg 0.0039 0.0039 0.0039 SC NP 1351 1850 m 1368 2002 l 1369 2003 1367 2005 1366 2005 c 1364 2005 1362 2004 1362 2002 c 1345 1851 l 1345 1849 1346 1848 1348 1848 c 1349 1847 1351 1849 1351 1850 c CP 1389 1991 m 1370 2043 l 1340 1997 l CP F GSE userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 0 GpPBeg 0.0039 0.0039 0.0039 SC NP 1349 1848 m 2416 2035 l 2418 2035 2419 2037 2419 2039 c 2418 2040 2417 2042 2415 2041 c 1348 1854 l 1346 1853 1345 1852 1345 1850 c 1345 1848 1347 1847 1349 1848 c CP 2412 2012 m 2456 2045 l 2403 2061 l CP F GSE 1 1 10 8.3333 [] 0 1 GpPBeg 0.0039 0.0039 0.0039 SC NP 2441 1389 m 2208 1389 2019 1490 2019 1614 c 2019 1738 2208 1839 2441 1839 c 2674 1839 2863 1738 2863 1614 c 2863 1490 2674 1389 2441 1389 c CP S GSE %%EndDocument Pscript_WinNT_Compat dup /suspend get exec Pscript_WinNT_Incr dup /resume get exec /DeviceRGB dup setcolorspace /colspABC exch def 0 0 0 1 scol F0S85 Ji 2280 1535 M (Show)[80 80 80 0]xS F1S64 Ji 2233 1670 M (All except)[72 28 28 25 44 51 44 44 51 0]xS 2285 1790 M (IO, \()[32 72 25 26 0]xS 2473 1790 M (-)S 2506 1790 M (>\))[56 0]xS Pscript_WinNT_Compat begin /$x mysetup def end Pscript_WinNT_Incr dup /suspend get exec Pscript_WinNT_Compat dup /initialize get exec %%BeginDocument: Pscript_Win_PassThrough userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 1 1 10 8.3333 [] 0 1 GpPBeg 0.0039 0.0039 0.0039 SC NP 2419 2786 m 2166 2786 1961 2888 1961 3014 c 1961 3139 2166 3241 2419 3241 c 2673 3241 2878 3139 2878 3014 c 2878 2888 2673 2786 2419 2786 c CP S GSE %%EndDocument Pscript_WinNT_Compat dup /suspend get exec Pscript_WinNT_Incr dup /resume get exec /DeviceRGB dup setcolorspace /colspABC exch def 0 0 0 1 scol F0S85 Ji 2259 2935 M (Real)[80 80 80 0]xS F1S64 Ji 2171 3070 M (Int)[32 50 0]xS 2281 3070 M (, Integer, )[25 27 32 50 29 45 49 45 33 25 0]xS 2144 3190 M (Float, Double)[55 28 50 44 28 25 25 72 50 50 50 29 0]xS Pscript_WinNT_Compat begin /$x mysetup def end Pscript_WinNT_Incr dup /suspend get exec Pscript_WinNT_Compat dup /initialize get exec %%BeginDocument: Pscript_Win_PassThrough userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 1 1 10 8.3333 [] 0 1 GpPBeg 0.0039 0.0039 0.0039 SC NP 3425 2791 m 3156 2791 2938 2891 2938 3014 c 2938 3137 3156 3236 3425 3236 c 3694 3236 3912 3137 3912 3014 c 3912 2891 3694 2791 3425 2791 c CP S GSE %%EndDocument Pscript_WinNT_Compat dup /suspend get exec Pscript_WinNT_Incr dup /resume get exec /DeviceRGB dup setcolorspace /colspABC exch def 0 0 0 1 scol F0S85 Ji 3024 2994 M (Fractional)[80 80 80 80 80 80 81 80 80 0]xS F1S64 Ji 3149 3130 M (Float, Double)[55 28 50 44 28 25 25 72 50 50 50 29 0]xS Pscript_WinNT_Compat begin /$x mysetup def end Pscript_WinNT_Incr dup /suspend get exec Pscript_WinNT_Compat dup /initialize get exec %%BeginDocument: Pscript_Win_PassThrough userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 1 1 10 8.3333 [] 0 1 GpPBeg 0.0039 0.0039 0.0039 SC NP 1358 2708 m 1060 2708 819 2845 819 3013 c 819 3182 1060 3318 1358 3318 c 1655 3318 1896 3182 1896 3013 c 1896 2845 1655 2708 1358 2708 c CP S GSE %%EndDocument Pscript_WinNT_Compat dup /suspend get exec Pscript_WinNT_Incr dup /resume get exec /DeviceRGB dup setcolorspace /colspABC exch def 0 0 0 1 scol F0S85 Ji 1197 2874 M (Enum)[80 80 80 0]xS F1S64 Ji 862 3010 M (\(\), )[33 33 25 0]xS 978 3010 M (Bool)[66 50 50 0]xS 1172 3010 M (, Char, Ordering,)[25 25 67 51 44 33 25 25 72 33 51 45 33 28 51 49 0]xS 994 3130 M (Int)[32 50 0]xS 1104 3130 M (, Integer, Float,)[25 27 32 50 29 45 49 45 33 25 25 55 28 51 44 28 0]xS 1210 3250 M (Double)[72 50 50 50 28 0]xS Pscript_WinNT_Compat begin /$x mysetup def end Pscript_WinNT_Incr dup /suspend get exec Pscript_WinNT_Compat dup /initialize get exec %%BeginDocument: Pscript_Win_PassThrough userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 1 1 10 8.3333 [] 0 1 GpPBeg 0.0039 0.0039 0.0039 SC NP 2379 3541 m 2158 3541 1979 3640 1979 3762 c 1979 3883 2158 3982 2379 3982 c 2600 3982 2778 3883 2778 3762 c 2778 3640 2600 3541 2379 3541 c CP S GSE %%EndDocument Pscript_WinNT_Compat dup /suspend get exec Pscript_WinNT_Incr dup /resume get exec /DeviceRGB dup setcolorspace /colspABC exch def 0 0 0 1 scol F0S85 Ji 2059 3742 M (RealFrac)[80 80 80 80 80 80 81 0]xS F1S64 Ji 2103 3878 M (Float, Double)[55 28 50 44 28 25 25 72 50 50 50 29 0]xS Pscript_WinNT_Compat begin /$x mysetup def end Pscript_WinNT_Incr dup /suspend get exec Pscript_WinNT_Compat dup /initialize get exec %%BeginDocument: Pscript_Win_PassThrough userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 1 1 10 8.3333 [] 0 1 GpPBeg 0.0039 0.0039 0.0039 SC NP 3301 3541 m 3057 3541 2859 3640 2859 3762 c 2859 3883 3057 3982 3301 3982 c 3545 3982 3743 3883 3743 3762 c 3743 3640 3545 3541 3301 3541 c CP S GSE %%EndDocument Pscript_WinNT_Compat dup /suspend get exec Pscript_WinNT_Incr dup /resume get exec /DeviceRGB dup setcolorspace /colspABC exch def 0 0 0 1 scol F0S85 Ji 2980 3742 M (Floating)[80 80 80 80 80 80 81 0]xS F1S64 Ji 3025 3878 M (Float, Double)[55 28 50 44 28 25 25 72 50 50 50 29 0]xS Pscript_WinNT_Compat begin /$x mysetup def end Pscript_WinNT_Incr dup /suspend get exec Pscript_WinNT_Compat dup /initialize get exec %%BeginDocument: Pscript_Win_PassThrough userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 1 1 10 8.3333 [] 0 1 GpPBeg 0.0039 0.0039 0.0039 SC NP 1461 3541 m 1244 3541 1068 3640 1068 3762 c 1068 3883 1244 3982 1461 3982 c 1678 3982 1854 3883 1854 3762 c 1854 3640 1678 3541 1461 3541 c CP S GSE %%EndDocument Pscript_WinNT_Compat dup /suspend get exec Pscript_WinNT_Incr dup /resume get exec /DeviceRGB dup setcolorspace /colspABC exch def 0 0 0 1 scol F0S85 Ji 1141 3742 M (Integral)[80 80 80 80 80 80 81 0]xS F1S64 Ji 1238 3878 M (Int)[32 50 0]xS 1348 3878 M (, Integer)[25 27 32 50 29 45 49 45 0]xS Pscript_WinNT_Compat begin /$x mysetup def end Pscript_WinNT_Incr dup /suspend get exec Pscript_WinNT_Compat dup /initialize get exec %%BeginDocument: Pscript_Win_PassThrough userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 1 1 10 8.3333 [] 0 1 GpPBeg 0.0039 0.0039 0.0039 SC NP 2718 4181 m 2463 4181 2256 4270 2256 4381 c 2256 4491 2463 4581 2718 4581 c 2973 4581 3179 4491 3179 4381 c 3179 4270 2973 4181 2718 4181 c CP S GSE %%EndDocument Pscript_WinNT_Compat dup /suspend get exec Pscript_WinNT_Incr dup /resume get exec /DeviceRGB dup setcolorspace /colspABC exch def 0 0 0 1 scol F0S85 Ji 2358 4362 M (RealFloat)[80 80 80 80 80 80 81 80 0]xS F1S64 Ji 2442 4498 M (Float, Double)[55 28 50 44 28 25 25 72 50 50 50 29 0]xS Pscript_WinNT_Compat begin /$x mysetup def end Pscript_WinNT_Incr dup /suspend get exec Pscript_WinNT_Compat dup /initialize get exec %%BeginDocument: Pscript_Win_PassThrough userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 0 GpPBeg 0.0039 0.0039 0.0039 SC NP 2444 1839 m 2456 2004 l 2457 2005 2455 2007 2454 2007 c 2452 2007 2450 2006 2450 2004 c 2438 1839 l 2438 1838 2439 1836 2441 1836 c 2442 1836 2444 1837 2444 1839 c CP 2478 1994 m 2456 2045 l 2428 1998 l CP F GSE userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 0 GpPBeg 0.0039 0.0039 0.0039 SC NP 1371 2524 m 2380 2773 l 2382 2773 2383 2775 2383 2777 c 2382 2779 2380 2780 2379 2779 c 1369 2530 l 1368 2529 1367 2528 1367 2526 c 1367 2524 1369 2523 1371 2524 c CP 2377 2750 m 2420 2786 l 2365 2798 l CP F GSE userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 0 GpPBeg 0.0039 0.0039 0.0039 SC NP 2460 2526 m 2429 2745 l 2429 2747 2427 2748 2425 2748 c 2424 2748 2422 2746 2423 2744 c 2453 2525 l 2454 2524 2455 2522 2457 2523 c 2459 2523 2460 2524 2460 2526 c CP 2452 2740 m 2420 2786 l 2402 2733 l CP F GSE userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 0 GpPBeg 0.0039 0.0039 0.0039 SC NP 2421 3244 m 1502 3532 l 1501 3532 1499 3531 1498 3530 c 1498 3528 1499 3526 1501 3526 c 2419 3238 l 2421 3238 2422 3239 2423 3240 c 2424 3242 2423 3244 2421 3244 c CP 1517 3550 m 1462 3541 l 1502 3503 l CP F GSE userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 0 GpPBeg 0.0039 0.0039 0.0039 SC NP 2423 3242 m 2388 3500 l 2388 3502 2386 3503 2385 3503 c 2383 3503 2382 3501 2382 3500 c 2417 3241 l 2417 3239 2419 3238 2420 3238 c 2422 3238 2423 3240 2423 3242 c CP 2411 3495 m 2379 3541 l 2361 3488 l CP F GSE userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 0 GpPBeg 0.0039 0.0039 0.0039 SC NP 3428 3237 m 3320 3504 l 3319 3505 3317 3506 3316 3506 c 3314 3505 3313 3503 3314 3502 c 3422 3235 l 3423 3233 3425 3233 3426 3233 c 3428 3234 3429 3236 3428 3237 c CP 3343 3504 m 3301 3541 l 3297 3486 l CP F GSE userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 0 GpPBeg 0.0039 0.0039 0.0039 SC NP 3426 3239 m 2420 3533 l 2419 3533 2417 3532 2416 3531 c 2416 3529 2417 3527 2419 3527 c 3424 3233 l 3426 3233 3428 3234 3428 3235 c 3429 3237 3428 3239 3426 3239 c CP 2434 3551 m 2379 3541 l 2420 3503 l CP F GSE userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 0 GpPBeg 0.0039 0.0039 0.0039 SC NP 3301 3985 m 2758 4170 l 2757 4171 2755 4170 2754 4168 c 2754 4167 2755 4165 2756 4164 c 3299 3979 l 3301 3978 3303 3979 3303 3981 c 3304 3983 3303 3984 3301 3985 c CP 2773 4188 m 2718 4181 l 2757 4141 l CP F GSE userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 0 GpPBeg 0.0039 0.0039 0.0039 SC NP 2381 3979 m 2684 4157 l 2685 4158 2686 4160 2685 4161 c 2684 4163 2682 4163 2680 4162 c 2378 3985 l 2376 3984 2376 3982 2377 3980 c 2378 3979 2379 3978 2381 3979 c CP 2687 4134 m 2718 4181 l 2662 4177 l CP F GSE userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 0 GpPBeg 0.0039 0.0039 0.0039 SC NP 1360 3317 m 1447 3502 l 1448 3504 1447 3506 1445 3506 c 1444 3507 1442 3506 1441 3505 c 1355 3320 l 1354 3318 1355 3316 1356 3316 c 1358 3315 1360 3315 1360 3317 c CP 1463 3485 m 1462 3541 l 1418 3507 l CP F GSE 1 1 10 8.3333 [] 0 1 GpPBeg 0.0039 0.0039 0.0039 SC NP 3399 1376 m 3209 1376 3055 1482 3055 1613 c 3055 1744 3209 1851 3399 1851 c 3589 1851 3743 1744 3743 1613 c 3743 1482 3589 1376 3399 1376 c CP S GSE %%EndDocument Pscript_WinNT_Compat dup /suspend get exec Pscript_WinNT_Incr dup /resume get exec /DeviceRGB dup setcolorspace /colspABC exch def 0 0 0 1 scol F0S85 Ji 3239 1534 M (Read)[80 80 80 0]xS F1S64 Ji 3192 1669 M (All except)[72 28 28 25 44 51 44 44 51 0]xS 3243 1789 M (IO, \()[32 72 25 26 0]xS 3431 1789 M (-)S 3464 1789 M (>\))[56 0]xS Pscript_WinNT_Compat begin /$x mysetup def end Pscript_WinNT_Incr dup /suspend get exec Pscript_WinNT_Compat dup /initialize get exec %%BeginDocument: Pscript_Win_PassThrough userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 1 1 10 8.3333 [] 0 1 GpPBeg 0.0039 0.0039 0.0039 SC NP 3506 2008 m 3265 2008 3069 2132 3069 2286 c 3069 2439 3265 2563 3506 2563 c 3748 2563 3944 2439 3944 2286 c 3944 2132 3748 2008 3506 2008 c CP S GSE %%EndDocument Pscript_WinNT_Compat dup /suspend get exec Pscript_WinNT_Incr dup /resume get exec /DeviceRGB dup setcolorspace /colspABC exch def 0 0 0 1 scol F0S85 Ji 3226 2207 M (Bounded)[80 80 80 80 80 80 0]xS F1S64 Ji 3148 2342 M (Int)[32 50 0]xS 3258 2342 M (, Char, )[25 25 67 51 44 33 25 0]xS 3554 2342 M (Bool)[66 50 50 0]xS 3748 2342 M (, \(\))[25 25 34 0]xS 3182 2462 M (Ordering, )[72 33 50 44 33 28 51 49 25 0]xS 3593 2462 M (tuples)[28 50 50 28 44 0]xS Pscript_WinNT_Compat begin /$x mysetup def end Pscript_WinNT_Incr dup /suspend get exec Pscript_WinNT_Compat dup /initialize get exec %%BeginDocument: Pscript_Win_PassThrough userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 1 1 10 8.3333 [] 0 1 GpPBeg 0.0039 0.0039 0.0039 SC NP 1640 4967 m 1396 4967 1198 5066 1198 5187 c 1198 5309 1396 5407 1640 5407 c 1885 5407 2083 5309 2083 5187 c 2083 5066 1885 4967 1640 4967 c CP S GSE %%EndDocument Pscript_WinNT_Compat dup /suspend get exec Pscript_WinNT_Incr dup /resume get exec /DeviceRGB dup setcolorspace /colspABC exch def 0 0 0 1 scol F0S85 Ji 1440 5168 M (Monad)[80 80 80 80 0]xS F1S64 Ji 1366 5304 M (IO, [], Maybe)[32 72 25 25 34 34 25 25 89 45 48 51 0]xS Pscript_WinNT_Compat begin /$x mysetup def end Pscript_WinNT_Incr dup /suspend get exec Pscript_WinNT_Compat dup /initialize get exec %%BeginDocument: Pscript_Win_PassThrough userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 1 1 10 8.3333 [] 0 1 GpPBeg 0.0039 0.0039 0.0039 SC NP 3057 4967 m 2813 4967 2615 5066 2615 5187 c 2615 5308 2813 5406 3057 5406 c 3301 5406 3499 5308 3499 5187 c 3499 5066 3301 4967 3057 4967 c CP S GSE %%EndDocument Pscript_WinNT_Compat dup /suspend get exec Pscript_WinNT_Incr dup /resume get exec /DeviceRGB dup setcolorspace /colspABC exch def 0 0 0 1 scol F0S85 Ji 2776 5167 M (Functor)[80 80 80 80 80 80 0]xS F1S64 Ji 2783 5303 M (IO, [], Maybe)[32 72 25 25 34 34 25 25 89 45 48 51 0]xS Pscript_WinNT_Compat begin /$x mysetup def end Pscript_WinNT_Incr dup /suspend get exec Pscript_WinNT_Compat dup /initialize get exec %%BeginDocument: Pscript_Win_PassThrough userdict /GpPBeg {gsave initclip 13 dict begin /c {curveto} bind def /l {lineto} bind def /m {moveto} bind def /NP {newpath} bind def /CP {closepath} bind def /SC {setrgbcolor} bind def /S {stroke} bind def /F {fill} bind def /AF {eofill} bind def 1 eq {setdash setlinewidth setmiterlimit setlinejoin setlinecap} if} put /GSE {end grestore} def 0 GpPBeg 0.0039 0.0039 0.0039 SC NP 2457 2523 m 3386 2777 l 3388 2778 3389 2779 3388 2781 c 3388 2783 3386 2784 3384 2783 c 2456 2529 l 2454 2528 2453 2527 2453 2525 c 2454 2523 2456 2522 2457 2523 c CP 3384 2754 m 3425 2791 l 3370 2802 l CP F GSE 1 1 10 8.3333 [] 0 1 GpPBeg 0.0039 0.0039 0.0039 SC NP 1277 1258 m 969 1258 719 1508 719 1816 c 719 5050 l 719 5358 969 5608 1277 5608 c 3511 5608 l 3819 5608 4069 5358 4069 5050 c 4069 1816 l 4069 1508 3819 1258 3511 1258 c CP S GSE %%EndDocument Pscript_WinNT_Compat dup /suspend get exec Pscript_WinNT_Incr dup /resume get exec LH %%PageTrailer %%Trailer %%DocumentNeededResources: %%+ font Courier-Bold %%+ font TimesNewRomanPSMT %%DocumentSuppliedResources: %%+ procset Pscript_WinNT_ErrorHandler 5.0 0 %%+ procset Pscript_FatalError 5.0 0 %%+ procset Pscript_Win_Basic 5.0 0 %%+ procset Pscript_Win_Utils_L2 5.0 0 %%+ procset Pscript_WinNT_Compat 5.0 0 %%+ procset Pscript_Text 5.0 0 %%+ procset Pscript_Encoding256 5.0 0 %%+ procset Pscript_Win_Euro_L2 5.0 0 Pscript_WinNT_Incr dup /terminate get exec %%EOF haskell98-report-20080907/report/decls.verb0000644000175000017500000023044111345221573017732 0ustar marcotmarcot% % $Header: /home/cvs/root/haskell-report/report/decls.verb,v 1.19 2003/01/13 13:08:55 simonpj Exp $ % %**The Haskell 98 Report: Declarations %*section 4 %**~header \section{Declarations and Bindings} \index{declaration} \index{binding} \label{declarations} In this chapter, we describe the syntax and informal semantics of \Haskell{} {\em declarations}. % including their translations into % the \Haskell{} kernel where appropriate. % (see Appendix~\ref{formal-semantics} for a complete formal semantics). @@@ module -> @module@ modid [exports] @where@ body | body body -> @{@ impdecls @;@ topdecls @}@ | @{@ impdecls @}@ | @{@ topdecls @}@ topdecls -> topdecl_1 @;@ ... @;@ topdecl_n & (n>=1) topdecl -> @type@ simpletype @=@ type | @data@ [context @=>@] simpletype @=@ constrs [deriving] | @newtype@ [context @=>@] simpletype @=@ newconstr [deriving] | @class@ [scontext @=>@] tycls tyvar [@where@ cdecls] | @instance@ [scontext @=>@] qtycls inst [@where@ idecls] | @default@ @(@type_1 @,@ ... @,@ type_n@)@ & \qquad (n>=0) | decl decls -> @{@ decl_1 @;@ ... @;@ decl_n @}@ & (n>=0) decl -> gendecl | (funlhs | pat^0) rhs cdecls -> @{@ cdecl_1 @;@ ... @;@ cdecl_n @}@ & (n>=0) cdecl -> gendecl | (funlhs | var) rhs idecls -> @{@ idecl_1 @;@ ... @;@ idecl_n @}@ & (n>=0) idecl -> (funlhs | var) rhs | & (\tr{empty}) gendecl -> vars @::@ [context @=>@] type & (\tr{type signature}) | fixity [integer] ops & (\tr{fixity declaration}) | & (\tr{empty declaration}) ops -> op_1 @,@ ... @,@ op_n & (n>=1) vars -> var_1 @,@ ... @,@ var_n & (n>=1) fixity -> @infixl@ | @infixr@ | @infix@ @@@ \indexsyn{vars}% \indexsyn{fixity}% \indexsyn{ops}% \indexsyn{topdecls}% \indexsyn{topdecl}% \indexsyn{gendecl}% \indexsyn{decls}% \indexsyn{decl}% \indexsyn{cdecls}% \indexsyn{cdecl}% \indexsyn{idecls}% \indexsyn{idecl}% The declarations in the syntactic category "topdecls" are only allowed at the top level of a \Haskell{} module (see Chapter~\ref{modules}), whereas "decls" may be used either at the top level or in nested scopes (i.e.~those within a @let@ or @where@ construct). For exposition, we divide the declarations into three groups: user-defined datatypes, consisting of @type@, @newtype@, and @data@ declarations (Section~\ref{user-defined-datatypes}); type classes and overloading, consisting of @class@, @instance@, and @default@ declarations (Section~\ref{overloading}); and nested declarations, consisting of value bindings, type signatures, and fixity declarations (Section~\ref{nested}). %The @module@ declaration, along with @import@ and %infix declarations, is described in Section~\ref{modules}. \Haskell{} has several primitive datatypes that are ``hard-wired'' (such as integers and floating-point numbers), but most ``built-in'' datatypes are defined with normal \Haskell{} code, using normal @type@ and @data@ declarations. % (see Section~\ref{user-defined-datatypes}). These ``built-in'' datatypes are described in detail in Section~\ref{basic-types}. \subsection{Overview of Types and Classes} \label{types-overview} \Haskell{} uses a traditional Hindley-Milner\index{Hindley-Milner type system} polymorphic type system to provide a static type semantics \cite{damas-milner82,hindley69}, but the type system has been extended with {\em type classes} (or just {\em classes}\index{class}) that provide a structured way to introduce {\em overloaded} functions.\index{type class} \index{constructor class} \index{overloaded functions} A @class@ declaration (Section~\ref{class-decls}) introduces a new {\em type class} and the overloaded operations that must be supported by any type that is an instance of that class. An @instance@ declaration (Section~\ref{instance-decls}) declares that a type is an {\em instance} of a class and includes the definitions of the overloaded operations---called {\em class methods}---instantiated on the named type. \index{class method} For example, suppose we wish to overload the operations @(+)@ and @negate@ on types @Int@ and @Float@. We introduce a new type class called @Num@:\nopagebreak[4] \par {\small \bprog @ class Num a where -- simplified class declaration for Num (+) :: a -> a -> a -- (Num is defined in the Prelude) negate :: a -> a @ \eprog } This declaration may be read ``a type @a@ is an instance of the class @Num@ if there are class methods @(+)@ and @negate@, of the given types, defined on it.'' We may then declare @Int@ and @Float@ to be instances of this class: \bprog @ instance Num Int where -- simplified instance of Num Int x + y = addInt x y negate x = negateInt x instance Num Float where -- simplified instance of Num Float x + y = addFloat x y negate x = negateFloat x @ \eprog where @addInt@, @negateInt@, @addFloat@, and @negateFloat@ are assumed in this case to be primitive functions, but in general could be any user-defined function. The first declaration above may be read ``@Int@ is an instance of the class @Num@ as witnessed by these definitions (i.e.~class methods)\index{class method} for @(+)@ and @negate@.'' More examples of type classes can be found in the papers by Jones \cite{jones:cclasses} or Wadler and Blott \cite{wadler:classes}. The term `type class' was used to describe the original \Haskell{} 1.0 type system; `constructor class' was used to describe an extension to the original type classes. There is no longer any reason to use two different terms: in this report, `type class' includes both the original \Haskell{} type classes and the constructor classes introduced by Jones. \subsubsection{Kinds} To ensure that they are valid, type expressions are classified into different {\em kinds}, \index{kind} which take one of two possible forms:\nopagebreak[4] \begin{itemize} \item The symbol $\ast$ represents the kind of all nullary type constructors. \item If $\kappa_1$ and $\kappa_2$ are kinds, then $\kappa_1\rightarrow\kappa_2$ is the kind of types that take a type of kind $\kappa_1$ and return a type of kind $\kappa_2$. \end{itemize} Kind inference checks the validity of type expressions in a similar way that type inference checks the validity of value expressions. However, unlike types, kinds are entirely implicit and are not a visible part of the language. Kind inference is discussed in Section~\ref{kindinference}. \subsubsection{Syntax of Types} \label{type-syntax} \index{type} \label{types} @@@ type -> btype [@->@ type] & (\tr{function type}) btype -> [btype] atype & (\tr{type application}) atype -> gtycon | tyvar | @(@ type_1 @,@ ... @,@ type_k @)@ & (\tr{tuple type}, k>=2) | @[@ type @]@ & (\tr{list type}) | @(@ type @)@ & (\tr{parenthesised constructor}) gtycon -> qtycon | @()@ & (\tr{unit type}) | @[]@ & (\tr{list constructor}) | @(->)@ & (\tr{function constructor}) | @(,@\{@,@\}@)@ & (\tr{tupling constructors}) @@@ \indexsyn{type}% \indexsyn{atype}% \indexsyn{btype}% \indexsyn{gtycon}% \noindent The syntax for \Haskell{} type expressions \index{type expression} \index{constructor expression} is given above. Just as data values are built using data constructors, type values are built from "type constructors". As with data constructors, the names of type constructors start with uppercase letters. Unlike data constructors, infix type constructors are not allowed (other than @(->)@). The main forms of type expression are as follows:\nopagebreak[4] \begin{enumerate} \item Type variables, written as identifiers beginning with a lowercase letter. The kind of a variable is determined implicitly by the context in which it appears. \item Type constructors. Most type constructors are written as an identifier beginning with an uppercase letter. For example:\nopagebreak[4] \begin{itemize} \item @Char@, @Int@, @Integer@, @Float@, @Double@ and @Bool@ are type constants with kind $\ast$. \item @Maybe@ and @IO@ are unary type constructors, and treated as types with kind $\ast\rightarrow\ast$. \item The declarations @data T ...@ or @newtype T ...@ add the type constructor @T@ to the type vocabulary. The kind of @T@ is determined by kind inference. \end{itemize} Special syntax is provided for certain built-in type constructors:\nopagebreak[4] \begin{itemize} \item The {\em trivial type}\index{trivial type} is written as @()@ and has kind $\ast$. It denotes the ``nullary tuple'' type, and has exactly one value, also written @()@ (see Sections~\ref{unit-expression} and~\ref{basic-trivial}). \item The {\em function type} is written as @(->)@ and has\index{function type} kind $\ast\rightarrow\ast\rightarrow\ast$. \item The {\em list type} is written as @[]@ and has kind $\ast\rightarrow\ast$.\index{list} \item The {\em tuple types} are written as @(,)@,\index{tuple} @(,,)@, and so on. Their kinds are $\ast\rightarrow\ast\rightarrow\ast$, $\ast\rightarrow\ast\rightarrow\ast\rightarrow\ast$, and so on. \end{itemize} Use of the @(->)@ and @[]@ constants is described in more detail below. \item Type application. If $t_1$ is a type of kind $\kappa_1\rightarrow\kappa_2$ and $t_2$ is a type of kind $\kappa_1$, then $t_1~t_2$ is a type expression of kind $\kappa_2$. \item A {\em parenthesized type}, having form "@(@t@)@", is identical to the type "t". \end{enumerate} For example, the type expression @IO a@ can be understood as the application of a constant, @IO@, to the variable @a@. Since the @IO@ type constructor has kind $\ast\rightarrow\ast$, it follows that both the variable @a@ and the whole expression, @IO a@, must have kind $\ast$. In general, a process of {\em kind inference}\index{kind}\index{kind inference} (see Section~\ref{kindinference}) is needed to determine appropriate kinds for user-defined datatypes, type synonyms, and classes. Special syntax is provided to allow certain type expressions to be written in a more traditional style:\nopagebreak[4] \begin{enumerate} \item A {\em function type}\index{function type} has the form "t_1 @->@ t_2", which is equivalent to the type "@(->)@ t_1 t_2". Function arrows associate to the right. For example, @Int -> Int -> Float@ means @Int -> (Int -> Float)@. \item A {\em tuple type}\index{tuple type} has the form "@(@t_1@,@ ... @,@ t_k@)@" where "k>=2", which is equivalent to the type "@(,@$\ldots$@,)@ t_1 ... t_k" where there are $k-1$ commas between the parenthesis. It denotes the type of "k"-tuples with the first component of type "t_1", the second component of type "t_2", and so on (see Sections~\ref{tuples} and \ref{basic-tuples}). \item A {\em list type}\index{list type} has the form "@[@t@]@", which is equivalent to the type "@[]@ t". It denotes the type of lists with elements of type "t" (see Sections~\ref{lists} and \ref{basic-lists}). \end{enumerate} These special syntactic forms always denote the built-in type constructors for functions, tuples, and lists, regardless of what is in scope. In a similar way, the prefix type constructors @(->)@, @[]@, @()@, @(,)@, and so on, always denote the built-in type constructors; they cannot be qualified, nor mentioned in import or export lists (Chapter~\ref{modules}). (Hence the special production, ``gtycon'', above.) Although the list and tuple types have special syntax, their semantics is the same as the equivalent user-defined algebraic data types. Notice that expressions and types have a consistent syntax. If "t_i" is the type of expression or pattern "e_i", then the expressions "@(\@ e_1 @->@ e_2@)@", "@[@e_1@]@", and "@(@e_1,e_2@)@" have the types "@(@t_1 @->@ t_2@)@", "@[@t_1@]@", and "@(@t_1,t_2@)@", respectively. \index{quantification} With one exception (that of the distinguished type variable in a class declaration (Section~\ref{class-decls})), the type variables in a \Haskell{} type expression are all assumed to be universally quantified; there is no explicit syntax for universal quantification~\cite{damas-milner82}. % \cite{damas-milner82,reynolds90}. For example, the type expression @a -> a@ denotes the type "\forall a.~a \rightarrow a". For clarity, however, we often write quantification explicitly when discussing the types of \Haskell{} programs. When we write an explicitly quantified type, the scope of the "\forall" extends as far to the right as possible; for example, "\forall a.~a \rightarrow a" means "\forall a.~(a \rightarrow a)". %Every type variable appearing in a signature %is universally quantified over that signature. This last %constraint implies that signatures such as: %\bprog %@@ % \ x -> ([x] :: [a]) %@@ %\eprog %are not valid, because this declares @[x]@ to be of type %"\forall a.@[@a@]@". In contrast, this {\em is} a valid signature: %@(\ x -> [x]) :: a -> [a]@; it declares that @(\ x -> [x])@ has type %"\forall a.a @->@ @[@a@]@". \subsubsection{Syntax of Class Assertions and Contexts} \index{class assertion} \index{context} \label{classes&contexts} @@@ context -> class | @(@ class_1 @,@ ... @,@ class_n @)@ & (n>=0) class -> qtycls tyvar | qtycls @(@ tyvar atype_1 ... atype_n @)@ & (n>=1) qtycls -> [ modid @.@ ] tycls tycls -> conid tyvar -> varid @@@ \indexsyn{context}% \indexsyn{class}% \indexsyn{simpleclass}% \indexsyn{tycls}% \indexsyn{tyvar}% A {\em class assertion} has form "qtycls tyvar", and indicates the membership of the type "tyvar" in the class "qtycls". A class identifier begins with an uppercase letter. A {\em context} consists of zero or more class assertions, and has the general form \[ "@(@ C_1 u_1, ..., C_n u_n @)@" \] where "C_1, ..., C_n" are class identifiers, and each of the "u_1, ..., u_n" is either a type variable, or the application of type variable to one or more types. The outer parentheses may be omitted when "n=1". In general, we use "cx" to denote a context and we write "cx @=>@ t" to indicate the type "t" restricted by the context "cx". The context "cx" must only contain type variables referenced in "t". For convenience, we write "cx @=>@ t" even if the context "cx" is empty, although in this case the concrete syntax contains no @=>@. \subsubsection{Semantics of Types and Classes} \label{type-semantics} In this section, we provide informal details of the type system. % the formal semantics is described in Appendix~\ref{static-semantics} (Wadler and Blott \cite{wadler:classes} and Jones \cite{jones:cclasses} discuss type and constructor classes, respectively, in more detail.) %A type is a {\em monotype\/}\index{monotype} if it contains no type %variables, and is {\em monomorphic\/} %\index{monomorphic type} %if it contains type variables %but is not polymorphic (in Milner's original terminology, %it is monomorphic if it contains no generic type variables). The \Haskell{} type system attributes a {\em type} to each \index{type} expression in the program. In general, a type is of the form "\forall \overline{u}.~cx \Rightarrow t", where "\overline{u}" is a set of type variables "u_1, ..., u_n". In any such type, any of the universally-quantified type variables "u_i" that are free in "cx" must also be free in "t". Furthermore, the context "cx" must be of the form given above in Section~\ref{classes&contexts}. For example, here are some valid types: \bprog @ Eq a => a -> a (Eq a, Show a, Eq b) => [a] -> [b] -> String (Eq (f a), Functor f) => (a -> b) -> f a -> f b -> Bool @ \eprog In the third type, the constraint @Eq (f a)@ cannot be made simpler because @f@ is universally quantified. The type of an expression "e" depends on a {\em type environment}\index{type environment} that gives types for the free variables in "e", and a {\em class environment}\index{class environment} that declares which types are instances of which classes (a type becomes an instance of a class only via the presence of an @instance@ declaration or a @deriving@ clause). Types are related by a generalization preorder \index{generalization preorder} (specified below); the most general type, up to the equivalence induced by the generalization preorder, that can be assigned to a particular expression (in a given environment) is called its {\em principal type}. \index{principal type} \Haskell{}'s extended Hindley-Milner type system can infer the principal type of all expressions, including the proper use of overloaded class methods (although certain ambiguous overloadings could arise, as described in Section~\ref{default-decls}). Therefore, explicit typings (called {\em type signatures}) \index{type signature} are usually optional (see Sections~\ref{expression-type-sigs} and~\ref{type-signatures}). The type "\forall \overline{u}.~cx_1 \Rightarrow t_1" is {\em more general than} the type "\forall \overline{w}.~cx_2 \Rightarrow t_2" if and only if there is a substitution "S" whose domain is "\overline{u}" such that: \begin{itemize} \item "t_2" is identical to "S(t_1)". \item Whenever "cx_2" holds in the class environment, "S(cx_1)" also holds. \end{itemize} A value of type "\forall \overline{u}.~cx \Rightarrow t", may be instantiated at types "\overline{s}" if and only if the context "cx[\overline{s}/\overline{u}]" holds. For example, consider the function @double@: \bprog @ double x = x + x @ \eprog The most general type of @double@ is "\forall a.~@Num@~a \Rightarrow a \rightarrow a". @double@ may be applied to values of type @Int@ (instantiating "a" to @Int@), since @Num Int@ holds, because @Int@ is an instance of the class @Num@. However, @double@ may not normally be applied to values of type @Char@, because @Char@ is not normally an instance of class @Num@. The user may choose to declare such an instance, in which case @double@ may indeed be applied to a @Char@. \subsection{User-Defined Datatypes} \index{datatype} \label{user-defined-datatypes} In this section, we describe algebraic datatypes (@data@ declarations), renamed datatypes (@newtype@ declarations), and type synonyms (@type@ declarations). These declarations may only appear at the top level of a module. \subsubsection{Algebraic Datatype Declarations} \index{algebraic datatype} \label{datatype-decls} @@@ topdecl -> @data@ [context @=>@] simpletype @=@ constrs [deriving] simpletype -> tycon tyvar_1 ... tyvar_k & (k>=0) constrs -> constr_1 @|@ ... @|@ constr_n & (n>=1) constr -> con [@!@] atype_1 ... [@!@] atype_k & (\tr{arity} con = k, k>=0) | (btype | @!@ atype) conop (btype | @!@ atype) & (\tr{infix} conop) | con @{@ fielddecl_1 @,@ ... @,@ fielddecl_n @}@ & (n>=0) fielddecl -> vars @::@ (type | @!@ atype) deriving -> @deriving@ (dclass | @(@dclass_1@,@ ... @,@ dclass_n@)@)& (n>=0) dclass -> qtycls @@@ \index{topdecl@@{\em topdecl} (@data@)}% \indexsyn{simpletype}% \indexsyn{constrs}% \indexsyn{constr}% \indexsyn{fielddecl}% \indexsyn{deriving}% \indexsyn{dclass}% \index{data declaration@@{\tt data} declaration} The precedence\index{precedence} for "constr" is the same as that for expressions---normal constructor application has higher precedence than infix constructor application (thus @a : Foo a@ parses as @a : (Foo a)@). An algebraic datatype declaration has the form: \[ "@data@ cx @=>@ T u_1 ... u_k @=@ K_1 t_{11} ... t_{1k_1} @|@ \cdots @|@ \ K_n t_{n1} ... t_{nk_n}" \] where "cx" is a context. %\index{context!in data declaration@@in {\tt data} declaration} This declaration introduces a new {\em type constructor} "T" with one or more constituent {\em data constructors} "K_1, ..., K_n". \index{data constructor}\index{type constructor} In this Report, the unqualified term ``constructor'' always means ``data constructor''. The types of the data constructors are given by: \[ "K_i :: \forall u_1 ... u_k.~ cx_i \Rightarrow t_{i1} \rightarrow \cdots \rightarrow t_{ik_i} \rightarrow (T u_1 ... u_k)" \] where "cx_i" is the largest subset of "cx" that constrains only those type variables free in the types "t_{i1}, ..., t_{ik_i}". The type variables "u_1" through "u_k" must be distinct and may appear in "cx" and the "t_{ij}"; it is a static error for any other type variable to appear in "cx" or on the right-hand-side. The new type constant "T" has a kind of the form $\kappa_1\rightarrow\ldots\rightarrow\kappa_k\rightarrow\ast$ where the kinds "\kappa_i" of the argument variables "u_i" are determined by kind inference as described in Section~\ref{kindinference}\index{kind}\index{kind inference}. This means that "T" may be used in type expressions with anywhere between "0" and "k" arguments. For example, the declaration \bprog @ data Eq a => Set a = NilSet | ConsSet a (Set a) @ \eprog introduces a type constructor @Set@ of kind $\ast\rightarrow\ast$, and constructors @NilSet@ and @ConsSet@ with types \[\ba{ll} @NilSet@ & ":: \forall a.~ @Set@~ a" \\ @ConsSet@ & ":: \forall a.~ @Eq@~ a \Rightarrow a \rightarrow @Set@~ a \rightarrow @Set@~ a" \ea\] In the example given, the overloaded type for @ConsSet@ ensures that @ConsSet@ can only be applied to values whose type is an instance of the class @Eq@. Pattern matching against @ConsSet@ also gives rise to an @Eq a@ constraint. For example: \bprog @ f (ConsSet a s) = a @ \eprog the function @f@ has inferred type @Eq a => Set a -> a@. The context in the @data@ declaration has no other effect whatsoever. The visibility of a datatype's constructors (i.e.~the ``abstractness'' \index{abstract datatype} of the datatype) outside of the module in which the datatype is defined is controlled by the form of the datatype's name in the export list as described in Section~\ref{abstract-types}. The optional "@deriving@" part of a @data@ declaration has to do with {\em derived instances}, and is described in Section~\ref{derived-decls}. \paragraph{Labelled Fields} \label{field-labels} \index{field label} A data constructor of arity "k" creates an object with "k" components. These components are normally accessed positionally as arguments to the constructor in expressions or patterns. For large datatypes it is useful to assign "field labels" to the components of a data object. This allows a specific field to be referenced independently of its location within the constructor. A constructor definition in a @data@ declaration may assign labels to the fields of the constructor, using the record syntax (@C { ... }@). Constructors using field labels may be freely mixed with constructors without them. A constructor with associated field labels may still be used as an ordinary constructor; features using labels are simply a shorthand for operations using an underlying positional constructor. The arguments to the positional constructor occur in the same order as the labeled fields. For example, the declaration \bprog @ data C = F { f1,f2 :: Int, f3 :: Bool } @ \eprog defines a type and constructor identical to the one produced by \bprog @ data C = F Int Int Bool @ \eprog Operations using field labels are described in Section~\ref{field-ops}. A @data@ declaration may use the same field label in multiple constructors as long as the typing of the field is the same in all cases after type synonym expansion. A label cannot be shared by more than one type in scope. Field names share the top level namespace with ordinary variables and class methods and must not conflict with other top level names in scope. The pattern @F {}@ matches any value built with constructor @F@, {\em whether or not @F@ was declared with record syntax}. \paragraph{Strictness Flags} \label{strictness-flags} \index{strictness flag} Whenever a data constructor is applied, each argument to the constructor is evaluated if and only if the corresponding type in the algebraic datatype declaration has a strictness flag, denoted by an exclamation point, ``@!@''. \index{""!@@{\tt {\char'041}}} Lexically, ``@!@'' is an ordinary varsym not a "reservedop"; it has special significance only in the context of the argument types of a data declaration. \outline{ \paragraph*{Translation:} A declaration of the form \[ "@data@ cx @=>@ T u_1 ... u_k @=@ ... @|@ K s_{1} ... s_{n} @|@ ... " \] where each "s_i" is either of the form @!@" t_i" or "t_i", replaces every occurrence of "K" in an expression by \[ "@(\ @x_1 ... x_n @->@ ( ((K op_1 x_1) op_2 x_2) ... ) op_n x_n)" \] where "op_i" is the non-strict apply function @$@ if "s_i" is of the form "t_i", and "op_i" is the strict apply function @$!@ (see Section~\ref{strict-eval}) if "s_i" is of the form "@!@ t_i". Pattern matching on "K" is not affected by strictness flags. } \subsubsection{Type Synonym Declarations} \index{type synonym} \label{type-synonym-decls} @@@ topdecl -> @type@ simpletype @=@ type simpletype -> tycon tyvar_1 ... tyvar_k & (k>=0) @@@ \index{topdecl@@{\em topdecl} (@type@)}% \indexsyn{simpletype}% A type synonym declaration introduces a new type that is equivalent to an old type. It has the form \[ "@type@ T u_1 ... u_k @=@ t" \] which introduces a new type constructor, "T". The type "(T t_1 ... t_k)" is equivalent to the type "t[t_1/u_1, ..., t_k/u_k]". The type variables "u_1" through "u_k" must be distinct and are scoped only over "t"; it is a static error for any other type variable to appear in "t". The kind of the new type constructor "T" is of the form $\kappa_1\rightarrow\ldots\rightarrow\kappa_k\rightarrow\kappa$ where the kinds "\kappa_i" of the arguments "u_i" and "\kappa" of the right hand side "t" are determined by kind inference as described in Section~\ref{kindinference}\index{kind}\index{kind inference}. For example, the following definition can be used to provide an alternative way of writing the list type constructor: \bprog @ type List = [] @ \eprog Type constructor symbols "T" introduced by type synonym declarations cannot be partially applied; it is a static error to use "T" without the full number of arguments. Although recursive and mutually recursive datatypes are allowed, \index{recursive datatype} \index{type synonym!recursive} this is not so for type synonyms, {\em unless an algebraic datatype intervenes}. For example, \bprog @ type Rec a = [Circ a] data Circ a = Tag [Rec a] @ \eprog is allowed, whereas \bprog @ type Rec a = [Circ a] -- invalid type Circ a = [Rec a] -- invalid @ \eprog is not. Similarly, @type Rec a = [Rec a]@ is not allowed. Type synonyms are a convenient, but strictly syntactic, mechanism to make type signatures more readable. A synonym and its definition are completely interchangeable, except in the instance type of an @instance@ declaration (Section~\ref{instance-decls}). \subsubsection{Datatype Renamings} \index{newtype declaration@@{\tt newtype} declaration} \label{datatype-renaming} @@@ topdecl -> @newtype@ [context @=>@] simpletype @=@ newconstr [deriving] newconstr -> con atype | con @{@ var @::@ type @}@ simpletype -> tycon tyvar_1 ... tyvar_k & (k>=0) @@@ \index{topdecl@@{\em topdecl} (@newtype@)}% \indexsyn{simpletype}% \indexsyn{newconstr}% \noindent \noindent A declaration of the form \[ "@newtype@ cx @=>@ T u_1 ... u_k @=@ N t" \] introduces a new type whose representation is the same as an existing type. The type "@(@T u_1 ... u_k@)@" renames the datatype "t". It differs from a type synonym in that it creates a distinct type that must be explicitly coerced to or from the original type. Also, unlike type synonyms, @newtype@ may be used to define recursive types. The constructor "N" in an expression coerces a value from type "t" to type "@(@T u_1 ... u_k@)@". Using "N" in a pattern coerces a value from type "@(@T u_1 ... u_k@)@" to type "t". These coercions may be implemented without execution time overhead; @newtype@ does not change the underlying representation of an object. New instances (see Section \ref{instance-decls}) can be defined for a type defined by @newtype@ but may not be defined for a type synonym. A type created by @newtype@ differs from an algebraic datatype in that the representation of an algebraic datatype has an extra level of indirection. This difference may make access to the representation less efficient. The difference is reflected in different rules for pattern matching (see Section~\ref{pattern-matching}). Unlike algebraic datatypes, the newtype constructor "N" is {\em unlifted}, so that "N \bot" is the same as "\bot". The following examples clarify the differences between @data@ (algebraic datatypes), @type@ (type synonyms), and @newtype@ (renaming types.) Given the declarations \bprog @ data D1 = D1 Int data D2 = D2 !Int type S = Int newtype N = N Int d1 (D1 i) = 42 d2 (D2 i) = 42 s i = 42 n (N i) = 42 @ \eprog the expressions "@(@ @d1@ \bot @)@", "@(@ @d2@ \bot @)@" and "@(d2 (D2@ \bot @) )@" are all equivalent to "\bot", whereas "@(@ @n@ \bot @)@", "@(@ @n@ @(@ @N @ \bot @) )@", "@(@ @d1@ @(@ @D1@ \bot @) )@" and "@(@ @s@ \bot @)@" are all equivalent to @42@. In particular, "@(@ @N@ \bot @)@" is equivalent to "\bot" while "@(@ @D1@ \bot @)@" is not equivalent to "\bot". The optional deriving part of a @newtype@ declaration is treated in the same way as the deriving component of a @data@ declaration; see Section~\ref{derived-decls}. A @newtype@ declaration may use field-naming syntax, though of course there may only be one field. Thus: \bprog @ newtype Age = Age { unAge :: Int } @ \eprog brings into scope both a constructor and a de-constructor: \bprog @ Age :: Int -> Age unAge :: Age -> Int @ \eprog \subsection{Type Classes and Overloading} \index{class} \index{overloading} \label{overloading} \label{classes} \subsubsection{Class Declarations} \index{class declaration} %\index{class declaration@@{\tt class} declaration} \label{class-decls} @@@ topdecl -> @class@ [scontext @=>@] tycls tyvar [@where@ cdecls] scontext -> simpleclass | @(@ simpleclass_1 @,@ ... @,@ simpleclass_n @)@ & (n>=0) simpleclass -> qtycls tyvar cdecls -> @{@ cdecl_1 @;@ ... @;@ cdecl_n @}@ & (n>=0) cdecl -> gendecl | (funlhs | var) rhs @@@ \index{topdecl@@{\em topdecl} (@class@)}% \indexsyn{gendecl}% \indexsyn{cdecls}% \indexsyn{cdecl}% \index{declaration!within a {\tt class} declaration} \noindent A {\em class declaration} introduces a new class and the operations ({\em class methods}) on it. A class declaration has the general form: \[\ba{rl} "@class@ cx @=>@ C u @where@ cdecls" % "@{@"&"...@;@ v_i @::@ cx_i @=>@ t_i @;@ ...@;@"\\ % &"...@;@ @infix@ n v_i@;@ ...@;@"\\ % &"valdef_1 @;@ ... @;@ valdef_m @}@" \ea\] This introduces a new class name "C"; the type variable "u" is scoped only over the class method signatures in the class body. The context "cx" specifies the superclasses\index{superclass} of "C", as described below; the only type variable that may be referred to in "cx" is "u". The superclass relation must not be cyclic; i.e.~it must form a directed acyclic graph.\index{superclass} The "cdecls" part of a @class@ declaration contains three kinds of declarations: \begin{itemize} \item The class declaration introduces new {\em class methods} \index{class method} "v_i", whose scope extends outside the @class@ declaration. The class methods of a class declaration are precisely the "v_i" for which there is an explicit type signature \[ "v_i @::@ cx_i @=>@ t_i" \] in "cdecls". Class methods share the top level namespace with variable bindings and field names; they must not conflict with other top level bindings in scope. That is, a class method can not have the same name as a top level definition, a field name, or another class method. The type of the top-level class method "v_i" is: \[ v_i :: \forall u,\overline{w}.~(C u, cx_i) \Rightarrow t_i \] The "t_i" must mention "u"; it may mention type variables "\overline{w}" other than "u", in which case the type of "v_i" is polymorphic in both "u" and "\overline{w}\/". The "cx_i" may constrain only "\overline{w}"; in particular, the "cx_i" may not constrain "u". For example: \bprog @ class Foo a where op :: Num b => a -> b -> a @ \eprog Here the type of @op@ is "\forall a, b.~(@Foo@~a,~@Num@~b)~ \Rightarrow a \rightarrow b \rightarrow a". \item The "cdecls" may also contain a {\em fixity declaration} for any of the class methods (but for no other values). \index{fixity declaration} However, since class methods declare top-level values, the fixity declaration for a class method may alternatively appear at top level, outside the class declaration. \item Lastly, the "cdecls" may contain a {\em default class method} \index{default class method} for any of the "v_i". The default class method for "v_i" is used if no binding for it is given in a particular @instance@ declaration (see Section~\ref{instance-decls}). The default method declaration is a normal value definition, except that the left hand side may only be a variable or function definition. For example: \bprog @ class Foo a where op1, op2 :: a -> a (op1, op2) = ... @ \eprog is not permitted, because the left hand side of the default declaration is a pattern. \end{itemize} Other than these cases, no other declarations are permitted in "cdecls". %Figure~\ref{standard-classes} shows some standard \Haskell{} classes, %including the use of superclasses. %; note the class inclusion diagram on the right. %For example, @Eq@ is a superclass of @Ord@, and thus in %any context @Ord a@ is equivalent to @(Eq a, Ord a)@. Figures~\ref{data-class}, %\ref{prelude-bool} and \ref{numeric-inclusions} show the remaining %standard \Haskell{} classes. A @class@ declaration with no @where@ part \index{class declaration!with an empty @where@ part} may be useful for combining a collection of classes into a larger one that inherits all of the class methods in the original ones. For example: \bprog @ class (Read a, Show a) => Textual a @ \eprog In such a case, if a type is an instance of all superclasses,\index{superclass} it is not {\em automatically} an instance of the subclass, even though the subclass has no immediate class methods. The @instance@ declaration must be given explicitly with no @where@ part. \index{instance declaration!with an empty @where@ part} \subsubsection{Instance Declarations} \label{instance-decls} \index{instance declaration} @@@ topdecl -> @instance@ [scontext @=>@] qtycls inst [@where@ idecls] inst -> gtycon | @(@ gtycon tyvar_1 ... tyvar_k @)@ & (k>=0, tyvars {\rm distinct}) | @(@ tyvar_1 @,@ ... @,@ tyvar_k @)@ & (k>=2, tyvars {\rm distinct}) | @[@ tyvar @]@ | @(@ tyvar_1 @->@ tyvar_2 @)@ & (tyvar_1 {\rm and} tyvar_2 {\rm distinct}) idecls -> @{@ idecl_1 @;@ ... @;@ idecl_n @}@ & (n>=0) idecl -> (funlhs | var) rhs | & (empty) @@@ \index{topdecl@@{\em topdecl} (@instance@)} \indexsyn{inst}% \indexsyn{valdefs}% \indexsyn{gtycon}% \indexsyn{idecl}% \indexsyn{idecls}% %\index{instance declaration@@{\tt instance} declaration} \index{declaration!within an {\tt instance} declaration} %\ToDo{tycls left off above} An {\em instance declaration} introduces an instance of a class. Let \[ "@class@ cx @=>@ C u @where@ @{@ cbody @}@" \] be a @class@ declaration. The general form of the corresponding instance declaration is: \[ "@instance@ cx' @=>@ C (T u_1 ... u_k) @where@ @{@ d @}@" \] where "k\geq0". The type "(T u_1 ... u_k)" must take the form of a type constructor "T" applied to simple type variables "u_1, ... u_k"; furthermore, "T" must not be a type synonym\index{type synonym}, and the "u_i" must all be distinct. This prohibits instance declarations such as: \bprog @ instance C (a,a) where ... instance C (Int,a) where ... instance C [[a]] where ... @ \eprog The declarations "d" may contain bindings only for the class methods\index{class method} of "C". It is illegal to give a binding for a class method that is not in scope, but the name under which it is in scope is immaterial; in particular, it may be a qualified name. (This rule is identical to that used for subordinate names in export lists --- Section~\ref{export}.) For example, this is legal, even though @range@ is in scope only with the qualified name @Ix.range@. \bprog @ module A where import qualified Ix instance Ix.Ix T where range = ... @ \eprog The declarations may not contain any type signatures or fixity declarations,\index{type signature}\index{fixity declaration} since these have already been given in the @class@ declaration. As in the case of default class methods \index{default class method}% (Section~\ref{class-decls}), the method declarations must take the form of a variable or function definition. % However, unlike other declarations, the name of the bound % variable may be qualified. So this is legal: % \bprog % % module A where % import qualified B( Foo(op) ) % instance B.Foo Int where % B.op = ... % %\eprog % Here, module @A@ imports class @Foo@ from module @B@, and then gives an %instance declaration for @Foo@. Since @B@ is imported @qualified@, the name %of the class method, @op@, is not in scope; so the definition must define @B.op@. % Hence the need for the "qfunlhs" and "qvar" left hand sides in "idecl". If no binding is given for some class method then the corresponding default class method \index{default class method} in the @class@ declaration is used (if present); if such a default does not exist then the class method of this instance is bound to @undefined@ and no compile-time error results. An @instance@ declaration that makes the type "T" to be an instance of class "C" is called a {\em C-T instance declaration} \index{instance declaration} and is subject to these static restrictions: %\index{instance declaration!with respect to modules} \begin{itemize} \item A type may not be declared as an instance of a particular class more than once in the program. \item The class and type must have the same kind; this can be determined using kind inference as described in Section~\ref{kindinference}\index{kind}\index{kind inference}. \item Assume that the type variables in the instance type "(T u_1 ... u_k)" satisfy the constraints in the instance context "cx'". Under this assumption, the following two conditions must also be satisfied: \begin{enumerate} \item The constraints expressed by the superclass context "cx[(T u1 ... uk)/u]" of "C" must be satisfied. In other words, "T" must be an instance of each of "C"'s superclasses and the contexts of all superclass instances must be implied by "cx'". \item Any constraints on the type variables in the instance type that are required for the class method declarations in "d" to be well-typed must also be satisfied. \end{enumerate} % "T" must be an instance of each of "C"'s superclasses. More precisely, % under the assumption that the constraints expressed by the % instance context "cx'" are satisfied, the constraints expressed by the % superclass context "cx[(T u1 ... uk)/u]" must also be satisfied. % % Furthermore, under the same assumption, any constraints arising from the % class method declarations in "d" must also be satisfied. In fact, except in pathological cases it is possible to infer from the instance declaration the most general instance context "cx'" satisfying the above two constraints, but it is nevertheless mandatory to write an explicit instance context. \end{itemize} The following example illustrates the restrictions imposed by superclass instances: \bprog @ class Foo a => Bar a where ... instance (Eq a, Show a) => Foo [a] where ... instance Num a => Bar [a] where ... @ \eprog This example is valid Haskell. Since @Foo@ is a superclass of @Bar@, the second instance declaration is only valid if @[a]@ is an instance of @Foo@ under the assumption @Num a@. The first instance declaration does indeed say that @[a]@ is an instance of @Foo@ under this assumption, because @Eq@ and @Show@ are superclasses of @Num@. If the two instance declarations instead read like this: \bprog @ instance Num a => Foo [a] where ... instance (Eq a, Show a) => Bar [a] where ... @ \eprog then the program would be invalid. The second instance declaration is valid only if @[a]@ is an instance of @Foo@ under the assumptions @(Eq a, Show a)@. But this does not hold, since @[a]@ is only an instance of @Foo@ under the stronger assumption @Num a@. Further examples of @instance@ declarations may be found in Chapter~\ref{stdprelude}. \subsubsection{Derived Instances} \index{derived instance} \label{derived-decls} As mentioned in Section~\ref{datatype-decls}, @data@ and @newtype@ declarations contain an optional @deriving@ form. If the form is included, then {\em derived instance declarations} are automatically generated for the datatype in each of the named classes. These instances are subject to the same restrictions as user-defined instances. When deriving a class "C" for a type "T", instances for all superclasses of "C" must exist for "T", either via an explicit @instance@ declaration or by including the superclass in the @deriving@ clause. Derived instances provide convenient commonly-used operations for user-de\-fined da\-ta\-types. For example, derived instances for datatypes in the class @Eq@ define the operations @==@ and @/=@, freeing the programmer from the need to define them. %and taking advantage of %\Haskell{}'s class mechanism to overload these operations. The only classes in the Prelude for which derived instances are allowed are @Eq@\indexdi{Eq}, @Ord@\indexdi{Ord}, @Enum@\indexdi{Enum}, @Bounded@\indexdi{Bounded}, @Show@\indexdi{Show}, and @Read@\indexdi{Read}, all mentioned in Figure~\ref{standard-classes}, page~\pageref{standard-classes}. The precise details of how the derived instances are generated for each of these classes are provided in Chapter~\ref{derived-appendix}, including a specification of when such derived instances are possible. %(which is important for the following discussion). Classes defined by the standard libraries may also be derivable. A static error results if it is not possible to derive an @instance@ declaration over a class named in a @deriving@ form. For example, not all datatypes can properly support class methods in @Enum@.\indexclass{Enum} It is also a static error to give an explicit @instance@ declaration for a class that is also derived. %These rules also apply to the superclasses %of the class in question. If the @deriving@ form is omitted from a @data@ or @newtype@ declaration, then {\em no} instance declarations are derived for that datatype; that is, omitting a @deriving@ form is equivalent to including an empty deriving form: @deriving ()@. % OLD: %On the other hand, if the @deriving@ form is omitted from a @data@ %declaration, then @instance@ declarations are derived for the datatype %in as many of the six classes mentioned above as is possible (see %Appendix~\ref{derived-appendix}); that is, no %static error will result if the @instance@ declarations cannot be generated. %OLD: %If {\em no} derived @instance@ declarations for a datatype %are wanted, then the empty deriving form @deriving ()@ must be given %in the @data@ declaration for that type. \subsubsection{Ambiguous Types, and Defaults for Overloaded Numeric Operations} \label{default-decls} \index{default declaration@@{\tt default} declaration} \index{overloading!defaults} @@@ topdecl -> @default@ @(@type_1 @,@ ... @,@ type_n@)@ & (n>=0) @@@ \index{topdecl@@{\em topdecl} (@default@)} \noindent A problem inherent with \Haskell{}-style overloading is the possibility of an {\em ambiguous type}. \index{ambiguous type} For example, using the @read@ and @show@ functions defined in Chapter~\ref{derived-appendix}, and supposing that just @Int@ and @Bool@ are members of @Read@ and @Show@, then the expression \bprog @ let x = read "..." in show x -- invalid @ \eprog is ambiguous, because the types for @show@ and @read@, \[\ba{ll} @show@ & ":: \forall a.~@Show@~ a \Rightarrow a \rightarrow @String@" \\ @read@ & ":: \forall a.~@Read@~ a \Rightarrow @String@ \rightarrow a" \ea\] could be satisfied by instantiating @a@ as either @Int@ in both cases, or @Bool@. Such expressions are considered ill-typed, a static error. We say that an expression @e@ has an {\em ambiguous type} if, in its type "\forall \overline{u}.~cx \Rightarrow t", there is a type variable "u" in "\overline{u}" that occurs in "cx" but not in "t". Such types are invalid. For example, the earlier expression involving @show@ and @read@ has an ambiguous type since its type is "\forall a.~ @Show@~ a, @Read@~ a \Rightarrow @String@". Ambiguous types can only be circumvented by input from the user. One way is through the use of {\em expression type-signatures} \index{expression type-signature} as described in Section~\ref{expression-type-sigs}. For example, for the ambiguous expression given earlier, one could write: \bprog @ let x = read "..." in show (x::Bool) @ \eprog which disambiguates the type. Occasionally, an otherwise ambiguous expression needs to be made the same type as some variable, rather than being given a fixed type with an expression type-signature. This is the purpose of the function @asTypeOf@ (Chapter~\ref{stdprelude}): "x" @`asTypeOf`@ "y" has the value of "x", but "x" and "y" are forced to have the same type. For example, \bprog @ approxSqrt x = encodeFloat 1 (exponent x `div` 2) `asTypeOf` x @ \eprog (See Section~\ref{coercion} for a description of @encodeFloat@ and @exponent@.) Ambiguities in the class @Num@\indexclass{Num} are most common, so \Haskell{} provides another way to resolve them---with a {\em default declaration}: \[ "@default (@t_1 @,@ ... @,@ t_n@)@" \] where "n\geq0", and each "t_i" must be a type for which "@Num @t_i" holds. In situations where an ambiguous type is discovered, an ambiguous type variable, "v", is defaultable if: \begin{itemize} \item "v" appears only in constraints of the form "C v", where "C" is a class, and \item at least one of these classes is a numeric class, (that is, @Num@ or a subclass of @Num@), and \item all of these classes are defined in the Prelude or a standard library (Figures~\ref{basic-numeric-1}--\ref{basic-numeric-2}, pages~\pageref{basic-numeric-1}--\pageref{basic-numeric-2} show the numeric classes, and Figure~\ref{standard-classes}, page~\pageref{standard-classes}, shows the classes defined in the Prelude.) \end{itemize} Each defaultable variable is replaced by the first type in the default list that is an instance of all the ambiguous variable's classes. It is a static error if no such type is found. Only one default declaration is permitted per module, and its effect is limited to that module. If no default declaration is given in a module then it assumed to be: \bprog @ default (Integer, Double) @ \eprog The empty default declaration, @default ()@, turns off all defaults in a module. \subsection{Nested Declarations} \label{nested} The following declarations may be used in any declaration list, including the top level of a module. \subsubsection{Type Signatures} \index{type signature} \label{type-signatures} @@@ gendecl -> vars @::@ [context @=>@] type vars -> var_1 @,@ ...@,@ var_n & (n>=1) @@@ \indexsyn{signdecl}% \indexsyn{vars}% A type signature specifies types for variables, possibly with respect to a context. A type signature has the form: \[ "v_1, ..., v_n @::@ cx @=>@ t" \] which is equivalent to asserting "v_i @::@ cx @=>@ t" for each "i" from "1" to "n". Each "v_i" must have a value binding in the same declaration list that contains the type signature; i.e.~it is invalid to give a type signature for a variable bound in an outer scope. Moreover, it is invalid to give more than one type signature for one variable, even if the signatures are identical. As mentioned in Section~\ref{type-syntax}, every type variable appearing in a signature is universally quantified over that signature, and hence the scope of a type variable is limited to the type signature that contains it. For example, in the following declarations \bprog @ f :: a -> a f x = x :: a -- invalid @ \eprog the @a@'s in the two type signatures are quite distinct. Indeed, these declarations contain a static error, since @x@ does not have type "\forall a.~a". (The type of @x@ is dependent on the type of @f@; there is currently no way in \Haskell{} to specify a signature for a variable with a dependent type; this is explained in Section \ref{monomorphism}.) If a given program includes a signature for a variable "f", then each use of "f" is treated as having the declared type. It is a static error if the same type cannot also be inferred for the defining occurrence of "f". If a variable "f" is defined without providing a corresponding type signature declaration, then each use of "f" outside its own declaration group (see Section~\ref{dependencyanalysis}) is treated as having the corresponding inferred, or {\em principal} type \index{principal type}. However, to ensure that type inference is still possible, the defining occurrence, and all uses of "f" within its declaration group must have the same monomorphic type (from which the principal type is obtained by generalization, as described in Section~\ref{generalization}). %%A type signature for "x" may be more specific than the principal %%type derivable from the value binding of "x" (see %%Section~\ref{type-semantics}), but it is an error to give a type %%that is more %%general than, or incomparable to, the principal type. %%\index{principal type} %%If a more specific type is given then all occurrences of the %%variable must be used at the more specific type or at a more %%specific type still. % For example, if we define\nopagebreak[4] \bprog @ sqr x = x*x @ \eprog then the principal type is "@sqr@ :: \forall a.~ @Num@~ a \Rightarrow a \rightarrow a", which allows applications such as @sqr 5@ or @sqr 0.1@. It is also valid to declare a more specific type, such as \bprog @ sqr :: Int -> Int @ \eprog but now applications such as @sqr 0.1@ are invalid. Type signatures such as \bprog @ sqr :: (Num a, Num b) => a -> b -- invalid sqr :: a -> a -- invalid @ \eprog are invalid, as they are more general than the principal type of @sqr@. Type signatures can also be used to support {\em polymorphic recursion}\index{polymorphic recursion}. The following definition is pathological, but illustrates how a type signature can be used to specify a type more general than the one that would be inferred: \bprog @ data T a = K (T Int) (T a) f :: T a -> a f (K x y) = if f x == 1 then f y else undefined @ \eprog If we remove the signature declaration, the type of @f@ will be inferred as @T Int -> Int@ due to the first recursive call for which the argument to @f@ is @T Int@. Polymorphic recursion allows the user to supply the more general type signature, @T a -> a@. \subsubsection{Fixity Declarations} \index{fixity declaration} \label{fixity} @@@ gendecl -> fixity [integer] ops fixity -> @infixl@ | @infixr@ | @infix@ ops -> op_1 @,@ ... @,@ op_n & (n>=1) op -> varop | conop @@@ \indexsyn{gendecl}% \indexsyn{fixity}% \indexsyn{ops}% \indexsyn{op}% %\indextt{infixl}\indextt{infixr}\indextt{infix} A fixity declaration gives the fixity and binding precedence of one or more operators. The "integer" in a fixity declaration must be in the range "0" to "9". A fixity declaration may appear anywhere that a type signature appears and, like a type signature, declares a property of a particular operator. Also like a type signature, a fixity declaration can only occur in the same sequence of declarations as the declaration of the operator itself, and at most one fixity declaration may be given for any operator. (Class methods are a minor exception; their fixity declarations can occur either in the class declaration itself or at top level.) There are three kinds of fixity, non-, left- and right-associativity (@infix@, @infixl@, and @infixr@, respectively), and ten precedence levels, 0 to 9 inclusive (level 0 binds least tightly, and level 9 binds most tightly). If the "digit" is omitted, level 9 is assumed. Any operator lacking a fixity declaration is assumed to be @infixl 9@ (See Section~\ref{expressions} for more on the use of fixities). Table~\ref{prelude-fixities} lists the fixities and precedences of the operators defined in the Prelude. \begin{table}[htb] \[ \centerline{ \bto{|r||l|l|l|} \hline Prec- & Left associative & Non-associative & Right associative \\ edence & operators & operators & operators \\ \hline\hline %9 & @!@, @!!@, @//@ & & @.@ \\ \hline 9 & @!!@ & & @.@ \\ \hline 8 & & & @^@, @^^@, @**@ \\ \hline 7 & @*@, @/@, @`div`@, & & \\ & @`mod`@, @`rem`@, @`quot`@ & & \\ \hline 6 & @+@, @-@ & & \\ \hline 5 & & & @:@, @++@ \\ \hline 4 & & @==@, @/=@, @<@, @<=@, @>@, @>=@, & \\ & & @`elem`@, @`notElem`@ & \\ \hline 3 & & & @&&@ \\ \hline 2 & & & @||@ \\ \hline 1 & @>>@, @>>=@ & & \\ \hline 0 & & & @$@, @$!@, @`seq`@ \\ \hline \eto} \] %**

Table 2

\ecaption{Precedences and fixities of prelude operators} % Removed (:%) -- infixl 7, on the grounds that it's not exported from % PreludeRatio! \label{prelude-fixities} \index{""!""!@@{\tt {\char'041}{\char'041}}} \indextt{.} \indextt{**} \index{^@@{\tt {\char'136}}} % this is ^ \index{^^@@{\tt {\char'136}{\char'136}}} % this is ^^ \indextt{*} \indextt{/} \indextt{div} \indextt{mod} \indextt{rem} \indextt{+} \indextt{-} \indextt{:} \indextt{++} \indextt{/=} \indextt{<} \indextt{<=} \indextt{==} \indextt{>} \indextt{>=} \indextt{elem} \indextt{notElem} \index{&&@@{\tt \&\&}} \index{""|""|@@{\tt {\char'174}{\char'174}}} \indextt{>>} \indextt{>>=} \index{$@@{\tt {\char'044}}} \end{table} % Old table % \begin{tabular}{|c|l|l|}\hline % Precedence & Fixity & Operators \\ \hline % 9 & @infixl@ & @!@, @!!@, @//@ \\ % & @infixr@ & @.@ \\ % 8 & @infixr@ & @**@, @^@, @^^@ \\ % 7 & @infixl@ & @%@, @*@ \\ % & @infix@ & @/@, @`div`@, @`mod`@, @`rem`@ \\ % 6 & @infixl@ & @+@, @-@ \\ % & @infix@ & @:+@ \\ % 5 & @infixr@ & @:@, @++@ \\ % & @infix@ & @\\@ \\ % 4 & @infix@ & @/=@, @<@, @<=@, @==@, @>@, @>=@, @`elem`@, @`notElem`@ \\ % 3 & @infixr@ & @&&@ \\ % 2 & @infixr@ & @||@ \\ % 1 & @infixr@ & @>>@, @>>=@ \\ % 0 & @infixr@ & @$@ \\ \hline % \end{tabular}} Fixity is a property of a particular entity (constructor or variable), just like its type; fixity is not a property of that entity's {\em name}. For example: \bprog @ module Bar( op ) where infixr 7 `op` op = ... module Foo where import qualified Bar infix 3 `op` a `op` b = (a `Bar.op` b) + 1 f x = let p `op` q = (p `Foo.op` q) * 2 in ... @ \eprog Here, @`Bar.op`@ is @infixr 7@, @`Foo.op`@ is @infix 3@, and the nested definition of @op@ in @f@'s right-hand side has the default fixity of @infixl 9@. (It would also be possible to give a fixity to the nested definition of @`op`@ with a nested fixity declaration.) \subsubsection{Function and Pattern Bindings} \label{function-bindings}\label{pattern-bindings} \index{function binding}\index{pattern binding} @@@ decl -> (funlhs | pat^0) rhs funlhs -> var apat \{ apat \} | pat^{i+1} varop^{(a,i)} pat^{i+1} | lpat^i varop^{({\rm{}l},i)} pat^{i+1} | pat^{i+1} varop^{({\rm{}r},i)} rpat^i | @(@ funlhs @)@ apat \{ apat \} rhs -> @=@ exp [@where@ decls] | gdrhs [@where@ decls] gdrhs -> gd @=@ exp [gdrhs] gd -> @|@ exp^0 @@@ \indexsyn{decl}% \indexsyn{rhs}% \indexsyn{gdrhs}% \indexsyn{gd}% We distinguish two cases within this syntax: a {\em pattern binding} occurs when the left hand side is a "pat^0"; otherwise, the binding is called a {\em function binding}. Either binding may appear at the top-level of a module or within a @where@ or @let@ construct. \subsubsubsection{Function bindings} \index{function binding} A function binding binds a variable to a function value. The general form of a function binding for variable "x" is: \[\ba{lll} "x" & "p_{11} ... p_{1k}" & "match_1"\\ "..." \\ "x" & "p_{n1} ... p_{nk}" & "match_n" \ea\] where each "p_{ij}" is a pattern, and where each "match_i" is of the general form: \[\ba{l} "@=@ e_i @where {@ decls_i @}@" \ea\] or \[\ba{lll} "@|@ g_{i1}" & "@=@ e_{i1} " \\ "..." \\ "@|@ g_{im_i}" & "@=@ e_{im_i}" \\ & \multicolumn{2}{l}{"@where {@ decls_i @}@"} \ea\] and where "n>=1", "1<=i<=n", "m_i>=1". The former is treated as shorthand for a particular case of the latter, namely: \[\ba{l} "@| True =@ e_i @where {@ decls_i @}@" \ea\] Note that all clauses defining a function must be contiguous, and the number of patterns in each clause must be the same. The set of patterns corresponding to each match must be {\em linear}\index{linearity}\index{linear pattern}---no variable is allowed to appear more than once in the entire set. Alternative syntax is provided for binding functional values to infix operators. For example, these three function definitions are all equivalent: \bprog @ plus x y z = x+y+z x @\bkqB@plus@\bkqA@ y = \ z -> x+y+z (x @\bkqB@plus@\bkqA@ y) z = x+y+z @ \eprogNoSkip \outline{ \paragraph*{Translation:} The general binding form for functions is semantically equivalent to the equation (i.e.~simple pattern binding): \[ "x @= \@ x_1 ... x_k @-> case (@x_1@, @...@, @x_k@) of@" \ba[t]{lcl} "@(@p_{11}, ..., p_{1k}@)@ match_1" \\ "..." \\ "@(@p_{n1}, ..., p_{nk}@)@ match_n" \ea\] where the "x_i" are new identifiers. } \subsubsubsection{Pattern bindings} \label{patbind} \index{pattern binding} A pattern binding binds variables to values. A {\em simple} pattern binding has form "p = e". \index{simple pattern binding} The pattern "p" is matched ``lazily'' as an irrefutable pattern\index{irrefutable pattern}, as if there were an implicit @~@ in front of it. See the translation in Section~\ref{let-expressions}. The {\em general} form of a pattern binding is "p match", where a "match" is the same structure as for function bindings above; in other words, a pattern binding is: \[\ba{rcl} "p" & "@|@ g_{1}" & "@=@ e_{1}" \\ & "@|@ g_{2}" & "@=@ e_{2}" \\ & "..." \\ & "@|@ g_{m}" & "@=@ e_{m}" \\ & \multicolumn{2}{l}{"@where {@ decls @}@"} \ea\] %{\em Note}: the simple form %\WeSay{Yes} %"p @=@ e" is equivalent to "p @| True =@ e". \outline{ \paragraph*{Translation:} The pattern binding above is semantically equivalent to this simple pattern binding: \[\ba{lcl} "p" &@=@& "@let@ decls @in@" \\ & & "@if @g_1@ then @e_1@ else@" \\ & & "@if @g_2@ then @e_2@ else@" \\ & & ... \\ & & "@if @g_m@ then @e_m@ else error "Unmatched pattern"@" \ea\] } \paragraph*{A note about syntax.} It is usually straightforward to tell whether a binding is a pattern binding or a function binding, but the existence of @n+k@ patterns\index{n+k pattern@@"n@+@k" pattern} sometimes confuses the issue. Here are four examples: \bprog @ x + 1 = ... -- Function binding, defines (+) -- Equivalent to (+) x 1 = ... (x + 1) = ... -- Pattern binding, defines x (x + 1) * y = ... -- Function binding, defines (*) -- Equivalent to (*) (x+1) y = ... (x + 1) y = ... -- Function binding, defines (+) -- Equivalent to (+) x 1 y = ... @ \eprog The first two can be distinguished because a pattern binding has a "pat^0" on the left hand side, not a "pat" --- the former cannot be an unparenthesised @n+k@ pattern. \subsection{Static Semantics of Function and Pattern Bindings} \label{dependencyanalysis} The static semantics of the function and pattern bindings of a @let@ expression or @where@ clause % (including that of the top-level of % a program that has been translated into a @let@ expression as % described at the beginning of Section~\ref{modules}) are discussed in this section. \subsubsection{Dependency Analysis} \label{depend-anal} In general the static semantics are given by the normal Hindley-Milner\index{Hindley-Milner type system} inference rules. A {\em dependency analysis\index{dependency analysis} transformation} is first performed to increase polymorphism. Two variables bound by value declarations are in the same {\em declaration group} if either \index{declaration group} \begin{enumerate} \item they are bound by the same pattern binding, or \item their bindings are mutually recursive (perhaps via some other declarations that are also part of the group). \end{enumerate} Application of the following rules causes each @let@ or @where@ construct (including the @where@ defining the top level bindings in a module) to bind only the variables of a single declaration group, thus capturing the required dependency analysis:\footnote{% A similar transformation is described in Peyton Jones' book \cite{peyton-jones:book}.} \begin{enumerate} \item The order of declarations in @where@/@let@ constructs is irrelevant. \item @let {@"d_1"@; @"d_2"@} in @"e" = @let {@"d_1"@} in (let {@"d_2"@} in @"e"@)@ \\ \ \ \ \ (when no identifier bound in "d_2" appears free in "d_1") \end{enumerate} %---------------- \subsubsection{Generalization} \label{generalization} The Hindley-Milner type system assigns types to a @let@-expression in two stages. First, the right-hand side of the declaration is typed, giving a type with no universal quantification. Second, all type variables that occur in this type are universally quantified unless they are associated with bound variables in the type environment; this is called {\em generalization}.\index{generalization} Finally, the body of the @let@-expression is typed. For example, consider the declaration \bprog @ f x = let g y = (y,y) in ... @ \eprog The type of @g@'s definition is "a \rightarrow (a,a)". The generalization step attributes to @g@ the polymorphic type "\forall a.~ a \rightarrow (a,a)", after which the typing of the ``@...@'' part can proceed. When typing overloaded definitions, all the overloading constraints from a single declaration group are collected together, to form the context for the type of each variable declared in the group. For example, in the definition: \bprog @ f x = let g1 x y = if x>y then show x else g2 y x g2 p q = g1 q p in ... @ \eprog The types of the definitions of @g1@ and @g2@ are both "a \rightarrow a \rightarrow @String@", and the accumulated constraints are "@Ord@~a" (arising from the use of @>@), and "@Show@~a" (arising from the use of @show@). The type variables appearing in this collection of constraints are called the {\em constrained type variables}. The generalization step attributes to both @g1@ and @g2@ the type \[ "\forall a.~(@Ord@~a,~@Show@~a) \Rightarrow a \rightarrow a \rightarrow @String@" \] Notice that @g2@ is overloaded in the same way as @g1@ even though the occurrences of @>@ and @show@ are in the definition of @g1@. If the programmer supplies explicit type signatures for more than one variable in a declaration group, the contexts of these signatures must be identical up to renaming of the type variables. \subsubsection{Context Reduction Errors} \label{context-reduction} \index{context reduction} As mentioned in Section~\ref{type-semantics}, the context of a type may constrain only a type variable, or the application of a type variable to one or more types. Hence, types produced by generalization must be expressed in a form in which all context constraints have be reduced to this ``head normal form''. Consider, for example, the definition: \bprog @ f xs y = xs == [y] @ \eprog Its type is given by \bprog @ f :: Eq a => [a] -> a -> Bool @ \eprog and not \bprog @ f :: Eq [a] => [a] -> a -> Bool @ \eprog Even though the equality is taken at the list type, the context must be simplified, using the instance declaration for @Eq@ on lists, before generalization. If no such instance is in scope, a static error occurs. Here is an example that shows the need for a constraint of the form "C (m t)" where m is one of the type variables being generalized; that is, where the class "C" applies to a type expression that is not a type variable or a type constructor. Consider: \bprog @ f :: (Monad m, Eq (m a)) => a -> m a -> Bool f x y = return x == y @ \eprog The type of @return@ is @Monad m => a -> m a@; the type of @(==)@ is @Eq a => a -> a -> Bool@. The type of @f@ should be therefore @(Monad m, Eq (m a)) => a -> m a -> Bool@, and the context cannot be simplified further. The instance declaration derived from a data type @deriving@ clause (see Section~\ref{derived-decls}) must, like any instance declaration, have a {\em simple} context; that is, all the constraints must be of the form "C a", where "a" is a type variable. For example, in the type \bprog @ data Apply a b = App (a b) deriving Show @ \eprog the derived Show instance will produce a context @Show (a b)@, which cannot be reduced and is not simple; thus a static error results. \subsubsection{Monomorphism} \label{monomorphism} Sometimes it is not possible to generalize over all the type variables used in the type of the definition. For example, consider the declaration\nopagebreak[4] \bprog @ f x = let g y z = ([x,y], z) in ... @ \eprog In an environment where @x@ has type "a", the type of @g@'s definition is "a \rightarrow b \rightarrow @([@a@]@,b@)@". The generalization step attributes to @g@ the type "\forall b.~ a \rightarrow b \rightarrow @([@a@]@,b@)@"; only "b" can be universally quantified because "a" occurs in the type environment. We say that the type of @g@ is {\em monomorphic in the type variable "a"}. \index{monomorphic type variable} The effect of such monomorphism is that the first argument of all applications of @g@ must be of a single type. For example, it would be valid for the ``@...@'' to be \bprog @ (g True, g False) @ \eprog (which would, incidentally, force @x@ to have type @Bool@) but invalid for it to be \bprog @ (g True, g 'c') @ \eprog In general, a type "\forall \overline{u}.~cx \Rightarrow t" is said to be {\em monomorphic} \index{monomorphic type variable} in the type variable "a" if "a" is free in "\forall \overline{u}.~cx \Rightarrow t". It is worth noting that the explicit type signatures provided by \Haskell{} are not powerful enough to express types that include monomorphic type variables. For example, we cannot write \bprog @ f x = let g :: a -> b -> ([a],b) g y z = ([x,y], z) in ... @ \eprog because that would claim that @g@ was polymorphic in both @a@ and @b@ (Section~\ref{type-signatures}). In this program, @g@ can only be given a type signature if its first argument is restricted to a type not involving type variables; for example \bprog @ g :: Int -> b -> ([Int],b) @ \eprog This signature would also cause @x@ to have type @Int@. \subsubsection{The Monomorphism Restriction} \index{monomorphism restriction} \label{sect:monomorphism-restriction} \Haskell{} places certain extra restrictions on the generalization step, beyond the standard Hindley-Milner restriction described above, which further reduces polymorphism in particular cases. The monomorphism restriction depends on the binding syntax of a variable. Recall that a variable is bound by either a {\em function binding} or a {\em pattern binding}, and that a {\em simple} pattern binding is a pattern binding in which the pattern consists of only a single variable (Section~\ref{pattern-bindings}). The following two rules define the monomorphism restriction: \outline{ \paragraph*{The monomorphism restriction} \begin{description} \item[Rule 1.] We say that a given declaration group is {\em unrestricted} if and only if: \begin{description} \item[(a):] every variable in the group is bound by a function binding or a simple pattern binding\index{simple pattern binding} (Section~\ref{patbind}), {\em and} \item[(b):] an explicit type signature is given for every variable in the group that is bound by simple pattern binding. \end{description} The usual Hindley-Milner restriction on polymorphism is that only type variables that do not occur free in the environment may be generalized. In addition, {\em the constrained type variables of a restricted declaration group may not be generalized} in the generalization step for that group. (Recall that a type variable is constrained if it must belong to some type class; see Section~\ref{generalization}.) % % \item[Rule 1.] % The variables of a given declaration group are monomorphic in % all their constrained type variables if and only if: % \begin{description} % \item[either (a):] % one or more variables in the declaration group % is bound by a non-simple pattern binding. % \item[or (b):] % one or more variables in the declaration group is bound % by a simple pattern binding, and % no type signature is given for any of the variables in the group. % \end{description} \item[Rule 2.] Any monomorphic type variables that remain when type inference for an entire module is complete, are considered {\em ambiguous}\index{ambiguous type}, and are resolved to particular types using the defaulting rules (Section~\ref{default-decls}). \end{description} } % When all variables in a declaration group are declared using function % binding the monomorphism restriction will not apply. Any variable % declared in a non-simple pattern binding will invoke monomorphism for % the entire group containing it. Simple pattern bindings will be % monomorphic unless a type signature is supplied. % \paragraph*{Motivation} Rule 1 is required for two reasons, both of which are fairly subtle. \begin{itemize} \item {\em Rule 1 prevents computations from being unexpectedly repeated.} For example, @genericLength@ is a standard function (in library @List@) whose type is given by \bprog @ genericLength :: Num a => [b] -> a @ \eprog Now consider the following expression: \bprog @ let { len = genericLength xs } in (len, len) @ \eprog It looks as if @len@ should be computed only once, but without Rule~1 it might be computed twice, once at each of two different overloadings. If the programmer does actually wish the computation to be repeated, an explicit type signature may be added: \bprog @ let { len :: Num a => a; len = genericLength xs } in (len, len) @ \eprog \item {\em Rule~1 prevents ambiguity.} For example, consider the declaration group \bprog @ [(n,s)] = reads t @ \eprog Recall that @reads@ is a standard function whose type is given by the signature \bprog @ reads :: (Read a) => String -> [(a,String)] @ \eprog Without Rule~1, @n@ would be assigned the type "\forall a.~@Read@~a \Rightarrow a" and @s@ the type "\forall a." "@Read@~a" "\Rightarrow @String@". The latter is an invalid type, because it is inherently ambiguous. It is not possible to determine at what overloading to use @s@, nor can this be solved by adding a type signature for @s@. Hence, when {\em non-simple} pattern bindings\index{simple pattern binding} are used (Section~\ref{patbind}), the types inferred are always monomorphic in their constrained type variables, irrespective of whether a type signature is provided. In this case, both @n@ and @s@ are monomorphic in "a". The same constraint applies to pattern-bound functions. For example, in \bprog @ (f,g) = ((+),(-)) @ \eprog both @f@ and @g@ are monomorphic regardless of any type signatures supplied for @f@ or @g@. \end{itemize} Rule~2 is required because there is no way to enforce monomorphic use of an {\em exported} binding, except by performing type inference on modules outside the current module. Rule~2 states that the exact types of all the variables bound in a module must be determined by that module alone, and not by any modules that import it. \bprog @ module M1(len1) where default( Int, Double ) len1 = genericLength "Hello" module M2 where import M1(len1) len2 = (2*len1) :: Rational @ \eprog When type inference on module @M1@ is complete, @len1@ has the monomorphic type @Num a => a@ (by Rule 1). Rule 2 now states that the monomorphic type variable @a@ is ambiguous, and must be resolved using the defaulting rules of Section~\ref{default-decls}. Hence, @len1@ gets type @Int@, and its use in @len2@ is type-incorrect. (If the above code is actually what is wanted, a type signature on @len1@ would solve the problem.) This issue does not arise for nested bindings, because their entire scope is visible to the compiler. \paragraph*{Consequences} The monomorphism rule has a number of consequences for the programmer. Anything defined with function syntax usually generalizes as a function is expected to. Thus in \bprog @ f x y = x+y @ \eprog the function @f@ may be used at any overloading in class @Num@. There is no danger of recomputation here. However, the same function defined with pattern syntax: \bprog @ f = \x -> \y -> x+y @ \eprog requires a type signature if @f@ is to be fully overloaded. Many functions are most naturally defined using simple pattern bindings; the user must be careful to affix these with type signatures to retain full overloading. The standard prelude contains many examples of this: \bprog @ sum :: (Num a) => [a] -> a sum = foldl (+) 0 @ \eprog Rule~1 applies to both top-level and nested definitions. Consider \bprog @ module M where len1 = genericLength "Hello" len2 = (2*len1) :: Rational @ \eprog Here, type inference finds that @len1@ has the monomorphic type (@Num a => a@); and the type variable @a@ is resolved to @Rational@ when performing type inference on @len2@. % Even when a function is defined using a function binding, it may still % be made monomorphic by another variable in the same declaration group. % Since groups defined through mutually recursive functions need not be % syntacticly adjacent, it may be difficult to see where overloading is % being lost. In this example @fact'@ is defined with a pattern binding % and forces @fact@ to be monomorphic in the absence of a type signature % for either @fact@ or @fact'@. This would in turn result in an error as % per Rule~2. % \bprog % % module Mod1(fact) % import Mod2 % fact 0 = 1 % fact n = n*fact'(n-1) % % module Mod2(fact') % import Mod1 % fact' = fact % % \eprog \subsection{Kind Inference} \index{kind} \index{kind inference} \label{kindinference} This section describes the rules that are used to perform {\em kind inference}, i.e. to calculate a suitable kind for each type constructor and class appearing in a given program. The first step in the kind inference process is to arrange the set of datatype, synonym, and class definitions into dependency groups. This can be achieved in much the same way as the dependency analysis for value declarations that was described in Section~\ref{dependencyanalysis}. For example, the following program fragment includes the definition of a datatype constructor @D@, a synonym @S@ and a class @C@, all of which would be included in the same dependency group: \bprog @ data C a => D a = Foo (S a) type S a = [D a] class C a where bar :: a -> D a -> Bool @ \eprog The kinds of variables, constructors, and classes within each group are determined using standard techniques of type inference and kind-preserving unification \cite{jones:cclasses}. For example, in the definitions above, the parameter @a@ appears as an argument of the function constructor @(->)@ in the type of @bar@ and hence must have kind $\ast$. It follows that both @D@ and @S@ must have kind $\ast\rightarrow\ast$ and that every instance of class @C@ must have kind $\ast$. % The kind of any constructor that is exported from a module without % exposing its definition must be specified explicitly in the interface % for that module. This is described in Section~\ref{somebodyneedstofillthisin}. It is possible that some parts of an inferred kind may not be fully determined by the corresponding definitions; in such cases, a default of $\ast$ is assumed. For example, we could assume an arbitrary kind $\kappa$ for the @a@ parameter in each of the following examples: \bprog @ data App f a = A (f a) data Tree a = Leaf | Fork (Tree a) (Tree a) @ \eprog This would give kinds $(\kappa\rightarrow\ast)\rightarrow\kappa\rightarrow\ast$ and $\kappa\rightarrow\ast$ for @App@ and @Tree@, respectively, for any kind $\kappa$, and would require an extension to allow polymorphic kinds. Instead, using the default binding $\kappa=\ast$, the actual kinds for these two constructors are $(\ast\rightarrow\ast)\rightarrow\ast\rightarrow\ast$ and $\ast\rightarrow\ast$, respectively. Defaults are applied to each dependency group without consideration of the ways in which particular type constructor constants or classes are used in later dependency groups or elsewhere in the program. For example, adding the following definition to those above does not influence the kind inferred for @Tree@ (by changing it to $(\ast\rightarrow\ast)\rightarrow\ast$, for instance), and instead generates a static error because the kind of @[]@, $\ast\rightarrow\ast$, does not match the kind $\ast$ that is expected for an argument of @Tree@: \bprog @ type FunnyTree = Tree [] -- invalid @ \eprog This is important because it ensures that each constructor and class are used consistently with the same kind whenever they are in scope. %**~footer % Local Variables: % mode: latex % End: haskell98-report-20080907/report/haskell.bbl0000644000175000017500000000450711345221573020066 0ustar marcotmarcot%**The Haskell 1.3 Report: Bibliography %**~eheader \begin{thebibliography}{10} \bibitem{back78} J.~Backus. \newblock Can programming be liberated from the von {N}eumann style? {A} functional style and its algebra of programs. \newblock {\em CACM}, 21(8):613--641, August 1978. \bibitem{curry&feys:book} H.B.~Curry and R.~Feys. \newblock {\em Combinatory Logic}. \newblock North-Holland Pub. Co., Amsterdam, 1958. \bibitem{damas-milner82} L.~Damas and R.~Milner. \newblock Principal type schemes for functional programs. \newblock In {\em Proceedings of the 9th ACM Symposium on Principles of Programming Languages}, pages 207--212, Albuquerque, N.M., January 1982. \bibitem{faxen:static} K-F.~Fax\'en \newblock A static semantics for Haskell \newblock {\em Journal of Functional Programming}, 2002. \bibitem{hindley69} J.R.~Hindley. \newblock The principal type scheme of an object in combinatory logic. \newblock {\em Transactions of the American Mathematical Society}, 146:29--60, December 1969. \bibitem{tutorial} P.~Hudak, J.~Fasel, and J.~Peterson. \newblock A gentle introduction to {H}askell. \newblock Technical Report YALEU/DCS/RR-901, Yale University, May 1996. \bibitem{jones:cclasses} Mark~P.~Jones. \newblock A system of constructor classes: overloading and implicit higher-order polymorphism. \newblock {\em Journal of Functional Programming}, 5(1), January 1995. \bibitem{jones:thih} Mark~P.~Jones. \newblock Typing Haskell in Haskell. \newblock {\em Haskell Workshop}, Paris, October 1999. \bibitem{penfield:complex-apl} P.~Penfield, Jr. \newblock Principal values and branch cuts in complex {APL}. \newblock In {\em APL '81 Conference Proceedings}, pages 248--256, San Francisco, September 1981. \bibitem{peyton-jones:book} S.L.~Peyton~Jones. \newblock {\em The Implementation of Functional Programming Languages}. \newblock Prentice-Hall International, Englewood Cliffs, New Jersey, 1987. \bibitem{unicode} {Unicode Consortium}. \newblock {\em The Unicode Standard, Version 3.0}. \newblock Addison Wesley, Reading, MA, 2000. \bibitem{wadler:classes} P.~Wadler and S.~Blott. \newblock How to make {\em ad hoc} polymorphism less {\em ad hoc}. \newblock In {\em Proceedings of the 16th ACM Symposium on Principles of Programming Languages}, pages 60--76, Austin, Texas, January 1989. \end{thebibliography} %**~efooter haskell98-report-20080907/report/lib-hdrs/0000755000175000017500000000000011345221573017460 5ustar marcotmarcothaskell98-report-20080907/report/lib-hdrs/IO1.hs0000644000175000017500000000347711345221573020417 0ustar marcotmarcothFileSize :: Handle -> IO Integer hIsEOF :: Handle -> IO Bool isEOF :: IO Bool isEOF = hIsEOF stdin hSetBuffering :: Handle -> BufferMode -> IO () hGetBuffering :: Handle -> IO BufferMode hFlush :: Handle -> IO () hGetPosn :: Handle -> IO HandlePosn hSetPosn :: HandlePosn -> IO () hSeek :: Handle -> SeekMode -> Integer -> IO () hWaitForInput :: Handle -> Int -> IO Bool hReady :: Handle -> IO Bool hReady h = hWaitForInput h 0 hGetChar :: Handle -> IO Char hGetLine :: Handle -> IO String hLookAhead :: Handle -> IO Char hGetContents :: Handle -> IO String hPutChar :: Handle -> Char -> IO () hPutStr :: Handle -> String -> IO () hPutStrLn :: Handle -> String -> IO () hPrint :: Show a => Handle -> a -> IO () hIsOpen :: Handle -> IO Bool hIsClosed :: Handle -> IO Bool hIsReadable :: Handle -> IO Bool hIsWritable :: Handle -> IO Bool hIsSeekable :: Handle -> IO Bool isAlreadyExistsError :: IOError -> Bool isDoesNotExistError :: IOError -> Bool isAlreadyInUseError :: IOError -> Bool isFullError :: IOError -> Bool isEOFError :: IOError -> Bool isIllegalOperation :: IOError -> Bool isPermissionError :: IOError -> Bool isUserError :: IOError -> Bool ioeGetErrorString :: IOError -> String ioeGetHandle :: IOError -> Maybe Handle ioeGetFileName :: IOError -> Maybe FilePath try :: IO a -> IO (Either IOError a) bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c haskell98-report-20080907/report/lib-hdrs/Numeric.hs0000644000175000017500000000237211345221573021422 0ustar marcotmarcotmodule Numeric(fromRat, showSigned, showIntAtBase, showInt, showOct, showHex, readSigned, readInt, readDec, readOct, readHex, floatToDigits, showEFloat, showFFloat, showGFloat, showFloat, 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 readDec :: (Integral a) => ReadS a readOct :: (Integral a) => ReadS a readHex :: (Integral a) => ReadS a showEFloat :: (RealFloat a) => Maybe Int -> a -> ShowS showFFloat :: (RealFloat a) => Maybe Int -> a -> ShowS showGFloat :: (RealFloat a) => Maybe Int -> a -> ShowS showFloat :: (RealFloat a) => a -> ShowS floatToDigits :: (RealFloat a) => Integer -> a -> ([Int], Int) readFloat :: (RealFrac a) => ReadS a lexDigits :: ReadS String haskell98-report-20080907/report/lib-hdrs/Random.hs0000644000175000017500000000245311345221573021240 0ustar marcotmarcotmodule Random ( RandomGen(next, split, genRange), StdGen, mkStdGen, Random( random, randomR, randoms, randomRs, randomIO, randomRIO ), getStdRandom, getStdGen, setStdGen, newStdGen ) where ---------------- The RandomGen class ------------------------ class RandomGen g where genRange :: g -> (Int, Int) next :: g -> (Int, g) split :: g -> (g, g) ---------------- A standard instance of RandomGen ----------- data StdGen = ... -- Abstract instance RandomGen StdGen where ... instance Read StdGen where ... instance Show StdGen where ... mkStdGen :: Int -> StdGen ---------------- The Random class --------------------------- class Random a where randomR :: RandomGen g => (a, a) -> g -> (a, g) random :: RandomGen g => g -> (a, g) randomRs :: RandomGen g => (a, a) -> g -> [a] randoms :: RandomGen g => g -> [a] randomRIO :: (a,a) -> IO a randomIO :: IO a instance Random Int where ... instance Random Integer where ... instance Random Float where ... instance Random Double where ... instance Random Bool where ... instance Random Char where ... ---------------- The global random generator ---------------- newStdGen :: IO StdGen setStdGen :: StdGen -> IO () getStdGen :: IO StdGen getStdRandom :: (StdGen -> (a, StdGen)) -> IO a haskell98-report-20080907/report/lib-hdrs/CPUTime.hs0000644000175000017500000000016411345221573021263 0ustar marcotmarcotmodule CPUTime ( getCPUTime, cpuTimePrecision ) where getCPUTime :: IO Integer cpuTimePrecision :: Integer haskell98-report-20080907/report/lib-hdrs/Ratio.hs0000644000175000017500000000152011345221573021070 0ustar marcotmarcotmodule Ratio ( Ratio, Rational, (%), numerator, denominator, approxRational ) where infixl 7 % data (Integral a) => Ratio a = ... type Rational = Ratio Integer (%) :: (Integral a) => a -> a -> Ratio a numerator, denominator :: (Integral a) => Ratio a -> a approxRational :: (RealFrac a) => a -> a -> Rational instance (Integral a) => Eq (Ratio a) where ... instance (Integral a) => Ord (Ratio a) where ... instance (Integral a) => Num (Ratio a) where ... instance (Integral a) => Real (Ratio a) where ... instance (Integral a) => Fractional (Ratio a) where ... instance (Integral a) => RealFrac (Ratio a) where ... instance (Integral a) => Enum (Ratio a) where ... instance (Read a,Integral a) => Read (Ratio a) where ... instance (Integral a) => Show (Ratio a) where ... haskell98-report-20080907/report/lib-hdrs/Monad.hs0000644000175000017500000000300211345221573021045 0ustar marcotmarcotmodule Monad ( MonadPlus(mzero, mplus), join, guard, when, unless, ap, msum, filterM, mapAndUnzipM, zipWithM, zipWithM_, foldM, liftM, liftM2, liftM3, liftM4, liftM5, -- ...and what the Prelude exports Monad((>>=), (>>), return, fail), Functor(fmap), mapM, mapM_, sequence, sequence_, (=<<), ) where class Monad m => MonadPlus m where mzero :: m a mplus :: m a -> m a -> m a join :: Monad m => m (m a) -> m a guard :: MonadPlus m => Bool -> m () when :: Monad m => Bool -> m () -> m () unless :: Monad m => Bool -> m () -> m () ap :: Monad m => m (a -> b) -> m a -> m b mapAndUnzipM :: Monad m => (a -> m (b,c)) -> [a] -> m ([b], [c]) zipWithM :: Monad m => (a -> b -> m c) -> [a] -> [b] -> m [c] zipWithM_ :: Monad m => (a -> b -> m c) -> [a] -> [b] -> m () foldM :: Monad m => (a -> b -> m a) -> a -> [b] -> m a filterM :: Monad m => (a -> m Bool) -> [a] -> m [a] msum :: MonadPlus m => [m a] -> m a liftM :: Monad m => (a -> b) -> (m a -> m b) liftM2 :: Monad m => (a -> b -> c) -> (m a -> m b -> m c) liftM3 :: Monad m => (a -> b -> c -> d) -> (m a -> m b -> m c -> m d) liftM4 :: Monad m => (a -> b -> c -> d -> e) -> (m a -> m b -> m c -> m d -> m e) liftM5 :: Monad m => (a -> b -> c -> d -> e -> f) -> (m a -> m b -> m c -> m d -> m e -> m f) haskell98-report-20080907/report/lib-hdrs/Maybe.hs0000644000175000017500000000075311345221573021056 0ustar marcotmarcotmodule Maybe( isJust, isNothing, fromJust, fromMaybe, listToMaybe, maybeToList, catMaybes, mapMaybe, -- ...and what the Prelude exports Maybe(Nothing, Just), maybe ) where isJust, isNothing :: Maybe a -> Bool fromJust :: Maybe a -> a fromMaybe :: a -> Maybe a -> a listToMaybe :: [a] -> Maybe a maybeToList :: Maybe a -> [a] catMaybes :: [Maybe a] -> [a] mapMaybe :: (a -> Maybe b) -> [a] -> [b] haskell98-report-20080907/report/lib-hdrs/Complex.hs0000644000175000017500000000157111345221573021427 0ustar marcotmarcotmodule Complex ( Complex((:+)), realPart, imagPart, conjugate, mkPolar, cis, polar, magnitude, phase ) where infix 6 :+ data (RealFloat a) => Complex a = !a :+ !a realPart, imagPart :: (RealFloat a) => Complex a -> a conjugate :: (RealFloat a) => Complex a -> Complex a mkPolar :: (RealFloat a) => a -> a -> Complex a cis :: (RealFloat a) => a -> Complex a polar :: (RealFloat a) => Complex a -> (a,a) magnitude, phase :: (RealFloat a) => Complex a -> a instance (RealFloat a) => Eq (Complex a) where ... instance (RealFloat a) => Read (Complex a) where ... instance (RealFloat a) => Show (Complex a) where ... instance (RealFloat a) => Num (Complex a) where ... instance (RealFloat a) => Fractional (Complex a) where ... instance (RealFloat a) => Floating (Complex a) where ... haskell98-report-20080907/report/lib-hdrs/Directory.hs0000644000175000017500000000231411345221573021760 0ustar marcotmarcotmodule Directory ( Permissions( Permissions, readable, writable, executable, searchable ), createDirectory, removeDirectory, removeFile, renameDirectory, renameFile, getDirectoryContents, getCurrentDirectory, setCurrentDirectory, doesFileExist, doesDirectoryExist, getPermissions, setPermissions, getModificationTime ) where import Time ( ClockTime ) data Permissions = Permissions { readable, writable, executable, searchable :: Bool } instance Eq Permissions where ... instance Ord Permissions where ... instance Read Permissions where ... instance Show Permissions where ... createDirectory :: FilePath -> IO () removeDirectory :: FilePath -> IO () removeFile :: FilePath -> IO () renameDirectory :: FilePath -> FilePath -> IO () renameFile :: FilePath -> FilePath -> IO () getDirectoryContents :: FilePath -> IO [FilePath] getCurrentDirectory :: IO FilePath setCurrentDirectory :: FilePath -> IO () doesFileExist :: FilePath -> IO Bool doesDirectoryExist :: FilePath -> IO Bool getPermissions :: FilePath -> IO Permissions setPermissions :: FilePath -> Permissions -> IO () getModificationTime :: FilePath -> IO ClockTime haskell98-report-20080907/report/lib-hdrs/Locale.hs0000644000175000017500000000072011345221573021212 0ustar marcotmarcotmodule Locale(TimeLocale(..), defaultTimeLocale) where data TimeLocale = TimeLocale { wDays :: [(String, String)], -- full and abbreviated week days months :: [(String, String)], -- full and abbreviated months amPm :: (String, String), -- AM/PM symbols dateTimeFmt, dateFmt, -- formatting strings timeFmt, time12Fmt :: String } deriving (Eq, Ord, Show) defaultTimeLocale :: TimeLocale haskell98-report-20080907/report/lib-hdrs/List.hs0000644000175000017500000000340511345221573020731 0ustar marcotmarcotmodule List ( elemIndex, elemIndices, find, findIndex, findIndices, nub, nubBy, delete, deleteBy, (\\), deleteFirstsBy, union, unionBy, intersect, intersectBy, intersperse, transpose, partition, group, groupBy, inits, tails, isPrefixOf, isSuffixOf, mapAccumL, mapAccumR, sort, sortBy, insert, insertBy, maximumBy, minimumBy, genericLength, genericTake, genericDrop, genericSplitAt, genericIndex, genericReplicate, zip4, zip5, zip6, zip7, zipWith4, zipWith5, zipWith6, zipWith7, 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, iterate, repeat, replicate, cycle, take, drop, splitAt, takeWhile, dropWhile, span, break, lines, words, unlines, unwords, reverse, and, or, any, all, elem, notElem, lookup, sum, product, maximum, minimum, concatMap, zip, zip3, zipWith, zipWith3, unzip, unzip3 ) where infix 5 \\ elemIndex :: Eq a => a -> [a] -> Maybe Int elemIndices :: Eq a => a -> [a] -> [Int] find :: (a -> Bool) -> [a] -> Maybe a findIndex :: (a -> Bool) -> [a] -> Maybe Int findIndices :: (a -> Bool) -> [a] -> [Int] nub :: Eq a => [a] -> [a] nubBy :: (a -> a -> Bool) -> [a] -> [a] delete :: Eq a => a -> [a] -> [a] deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a] (\\) :: Eq a => [a] -> [a] -> [a] deleteFirstsBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] union :: Eq a => [a] -> [a] -> [a] unionBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] haskell98-report-20080907/report/lib-hdrs/IO.hs0000644000175000017500000000352311345221573020326 0ustar marcotmarcotmodule IO ( Handle, HandlePosn, IOMode(ReadMode,WriteMode,AppendMode,ReadWriteMode), BufferMode(NoBuffering,LineBuffering,BlockBuffering), SeekMode(AbsoluteSeek,RelativeSeek,SeekFromEnd), stdin, stdout, stderr, openFile, hClose, hFileSize, hIsEOF, isEOF, hSetBuffering, hGetBuffering, hFlush, hGetPosn, hSetPosn, hSeek, hWaitForInput, hReady, hGetChar, hGetLine, hLookAhead, hGetContents, hPutChar, hPutStr, hPutStrLn, hPrint, hIsOpen, hIsClosed, hIsReadable, hIsWritable, hIsSeekable, isAlreadyExistsError, isDoesNotExistError, isAlreadyInUseError, isFullError, isEOFError, isIllegalOperation, isPermissionError, isUserError, ioeGetErrorString, ioeGetHandle, ioeGetFileName, try, bracket, bracket_, -- ...and what the Prelude exports IO, FilePath, IOError, ioError, userError, catch, interact, putChar, putStr, putStrLn, print, getChar, getLine, getContents, readFile, writeFile, appendFile, readIO, readLn ) where import Ix(Ix) data Handle = ... -- implementation-dependent instance Eq Handle where ... instance Show Handle where .. -- implementation-dependent data HandlePosn = ... -- implementation-dependent instance Eq HandlePosn where ... instance Show HandlePosn where --- -- implementation-dependent data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode deriving (Eq, Ord, Ix, Bounded, Enum, Read, Show) data BufferMode = NoBuffering | LineBuffering | BlockBuffering (Maybe Int) deriving (Eq, Ord, Read, Show) data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd deriving (Eq, Ord, Ix, Bounded, Enum, Read, Show) stdin, stdout, stderr :: Handle openFile :: FilePath -> IOMode -> IO Handle hClose :: Handle -> IO () haskell98-report-20080907/report/lib-hdrs/Ix.hs0000644000175000017500000000103311345221573020371 0ustar marcotmarcotmodule Ix ( Ix(range, index, inRange, rangeSize) ) where class Ord a => Ix a where range :: (a,a) -> [a] index :: (a,a) -> a -> Int inRange :: (a,a) -> a -> Bool rangeSize :: (a,a) -> Int instance Ix Char where ... instance Ix Int where ... instance Ix Integer where ... instance (Ix a, Ix b) => Ix (a,b) where ... -- et cetera instance Ix Bool where ... instance Ix Ordering where ... haskell98-report-20080907/report/lib-hdrs/Time.hs0000644000175000017500000000303611345221573020714 0ustar marcotmarcotmodule Time ( ClockTime, Month(January,February,March,April,May,June, July,August,September,October,November,December), Day(Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday), CalendarTime(CalendarTime, ctYear, ctMonth, ctDay, ctHour, ctMin, ctSec, ctPicosec, ctWDay, ctYDay, ctTZName, ctTZ, ctIsDST), TimeDiff(TimeDiff, tdYear, tdMonth, tdDay, tdHour, tdMin, tdSec, tdPicosec), getClockTime, addToClockTime, diffClockTimes, toCalendarTime, toUTCTime, toClockTime, calendarTimeToString, formatCalendarTime ) where import Ix(Ix) data ClockTime = ... -- Implementation-dependent instance Ord ClockTime where ... instance Eq ClockTime where ... data Month = January | February | March | April | May | June | July | August | September | October | November | December deriving (Eq, Ord, Enum, Bounded, Ix, Read, Show) data Day = Sunday | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday deriving (Eq, Ord, Enum, Bounded, Ix, Read, Show) data CalendarTime = CalendarTime { ctYear :: Int, ctMonth :: Month, ctDay, ctHour, ctMin, ctSec :: Int, ctPicosec :: Integer, ctWDay :: Day, ctYDay :: Int, ctTZName :: String, ctTZ :: Int, ctIsDST :: Bool } deriving (Eq, Ord, Read, Show) data TimeDiff = TimeDiff { tdYear, tdMonth, tdDay, tdHour, tdMin, tdSec :: Int, tdPicosec :: Integer } deriving (Eq, Ord, Read, Show) haskell98-report-20080907/report/lib-hdrs/List1.hs0000644000175000017500000000421111345221573021006 0ustar marcotmarcotintersect :: Eq a => [a] -> [a] -> [a] intersectBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] intersperse :: a -> [a] -> [a] transpose :: [[a]] -> [[a]] partition :: (a -> Bool) -> [a] -> ([a],[a]) group :: Eq a => [a] -> [[a]] groupBy :: (a -> a -> Bool) -> [a] -> [[a]] inits :: [a] -> [[a]] tails :: [a] -> [[a]] isPrefixOf :: Eq a => [a] -> [a] -> Bool isSuffixOf :: Eq a => [a] -> [a] -> Bool mapAccumL :: (a -> b -> (a, c)) -> a -> [b] -> (a, [c]) mapAccumR :: (a -> b -> (a, c)) -> a -> [b] -> (a, [c]) unfoldr :: (b -> Maybe (a,b)) -> b -> [a] sort :: Ord a => [a] -> [a] sortBy :: (a -> a -> Ordering) -> [a] -> [a] insert :: Ord a => a -> [a] -> [a] insertBy :: (a -> a -> Ordering) -> a -> [a] -> [a] maximumBy :: (a -> a -> Ordering) -> [a] -> a minimumBy :: (a -> a -> Ordering) -> [a] -> a genericLength :: Integral a => [b] -> a genericTake :: Integral a => a -> [b] -> [b] genericDrop :: Integral a => a -> [b] -> [b] genericSplitAt :: Integral a => a -> [b] -> ([b],[b]) genericIndex :: Integral a => [b] -> a -> b genericReplicate :: Integral a => a -> b -> [b] zip4 :: [a] -> [b] -> [c] -> [d] -> [(a,b,c,d)] zip5 :: [a] -> [b] -> [c] -> [d] -> [e] -> [(a,b,c,d,e)] zip6 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [(a,b,c,d,e,f)] zip7 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g] -> [(a,b,c,d,e,f,g)] zipWith4 :: (a->b->c->d->e) -> [a]->[b]->[c]->[d]->[e] zipWith5 :: (a->b->c->d->e->f) -> [a]->[b]->[c]->[d]->[e]->[f] zipWith6 :: (a->b->c->d->e->f->g) -> [a]->[b]->[c]->[d]->[e]->[f]->[g] zipWith7 :: (a->b->c->d->e->f->g->h) -> [a]->[b]->[c]->[d]->[e]->[f]->[g]->[h] unzip4 :: [(a,b,c,d)] -> ([a],[b],[c],[d]) unzip5 :: [(a,b,c,d,e)] -> ([a],[b],[c],[d],[e]) unzip6 :: [(a,b,c,d,e,f)] -> ([a],[b],[c],[d],[e],[f]) unzip7 :: [(a,b,c,d,e,f,g)] -> ([a],[b],[c],[d],[e],[f],[g]) haskell98-report-20080907/report/lib-hdrs/Time1.hs0000644000175000017500000000072711345221573021001 0ustar marcotmarcot-- Functions on times getClockTime :: IO ClockTime addToClockTime :: TimeDiff -> ClockTime -> ClockTime diffClockTimes :: ClockTime -> ClockTime -> TimeDiff toCalendarTime :: ClockTime -> IO CalendarTime toUTCTime :: ClockTime -> CalendarTime toClockTime :: CalendarTime -> ClockTime calendarTimeToString :: CalendarTime -> String formatCalendarTime :: TimeLocale -> String -> CalendarTime -> String haskell98-report-20080907/report/lib-hdrs/Char.hs0000644000175000017500000000125711345221573020676 0ustar marcotmarcotmodule 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 isAscii, isLatin1, isControl, isPrint, isSpace, isUpper, isLower, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum :: Char -> Bool toUpper, toLower :: Char -> Char digitToInt :: Char -> Int intToDigit :: Int -> Char ord :: Char -> Int chr :: Int -> Char lexLitChar :: ReadS String readLitChar :: ReadS Char showLitChar :: Char -> ShowS haskell98-report-20080907/report/lib-hdrs/Array.hs0000644000175000017500000000246511345221573021101 0ustar marcotmarcotmodule Array ( module Ix, -- export all of Ix for convenience Array, array, listArray, (!), bounds, indices, elems, assocs, accumArray, (//), accum, ixmap ) where import Ix infixl 9 !, // data (Ix a) => Array a b = ... -- Abstract array :: (Ix a) => (a,a) -> [(a,b)] -> Array a b listArray :: (Ix a) => (a,a) -> [b] -> Array a b (!) :: (Ix a) => Array a b -> a -> b bounds :: (Ix a) => Array a b -> (a,a) indices :: (Ix a) => Array a b -> [a] elems :: (Ix a) => Array a b -> [b] assocs :: (Ix a) => Array a b -> [(a,b)] accumArray :: (Ix a) => (b -> c -> b) -> b -> (a,a) -> [(a,c)] -> Array a b (//) :: (Ix a) => Array a b -> [(a,b)] -> Array a b accum :: (Ix a) => (b -> c -> b) -> Array a b -> [(a,c)] -> Array a b ixmap :: (Ix a, Ix b) => (a,a) -> (a -> b) -> Array b c -> Array a c instance Functor (Array a) where ... instance (Ix a, Eq b) => Eq (Array a b) where ... instance (Ix a, Ord b) => Ord (Array a b) where ... instance (Ix a, Show a, Show b) => Show (Array a b) where ... instance (Ix a, Read a, Read b) => Read (Array a b) where ... haskell98-report-20080907/report/lib-hdrs/System.hs0000644000175000017500000000063411345221573021303 0ustar marcotmarcotmodule System ( ExitCode(ExitSuccess,ExitFailure), getArgs, getProgName, getEnv, system, exitWith, exitFailure ) where data ExitCode = ExitSuccess | ExitFailure Int deriving (Eq, Ord, Read, Show) getArgs :: IO [String] getProgName :: IO String getEnv :: String -> IO String system :: String -> IO ExitCode exitWith :: ExitCode -> IO a exitFailure :: IO a haskell98-report-20080907/report/index.html0000644000175000017500000001043011345221573017747 0ustar marcotmarcotThe Haskell 98 Language Report
Haskell 98

Haskell 98 Language and Libraries

The Revised Report

December 2002


Brief Table of Contents

Part I: Language

  1. Introduction
  2. Lexical Structure
  3. Expressions
  4. Declarations and Bindings
  5. Modules
  6. Predefined Types and Classes
  7. Basic Input/Output
  8. Standard Prelude
  9. Syntax Reference
  10. Specification of Derived Instances
  11. Compiler Pragmas

Part II: Libraries

  1. Ratio
  2. Complex
  3. Numeric
  4. Ix
  5. Array
  6. List
  7. Maybe
  8. Char
  1. Monad
  2. IO
  3. Directory
  4. System
  5. Time
  6. Locale
  7. CPUTime
  8. Random

Simon Peyton Jones [editor], Microsoft Research, Cambridge
Lennart Augustsson, Sandburst Corporation
Dave Barton, Intermetrics
Brian Boutel, Victoria University of Wellington
Warren Burton, Simon Fraser University
Joseph Fasel, Los Alamos National Laboratory
Kevin Hammond, University of St. Andrews
Ralf Hinze, University of Bonn
Paul Hudak, Yale University
John Hughes, Chalmers University of Technology
Thomas Johnsson, Chalmers University of Technology
Mark Jones, Oregon Graduate Institute
John Launchbury, Oregon Graduate Institute
Erik Meijer, Microsoft Corporation
John Peterson, Yale University
Alastair Reid, University of Utah
Colin Runciman, York University
Philip Wadler, Avaya Labs

Copyright (c) Simon Peyton Jones.
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 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 a definition of the language Haskell 98.

The master version of the Haskell Report is at haskell.org. Any corrections or changes in the report are found there. haskell98-report-20080907/report/char.verb0000644000175000017500000000634311345221573017557 0ustar marcotmarcot%**The Haskell 98 Library Report: Character Utilities %**~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 haskell98-report-20080907/report/lexemes.verb0000644000175000017500000004653111345221573020307 0ustar marcotmarcot% % $Header: /home/cvs/root/haskell-report/report/lexemes.verb,v 1.14 2003/01/13 13:08:55 simonpj Exp $ % %*section 2 %**Haskell 98 Lexical Structure %**~header \section{Lexical Structure}\index{lexical structure} \label{lexical-structure} % this quote is not in because: it is supposed to show Curry as an % early advocate of abstract syntax. However, as far as I know (which % I can't be sure w/out going to the library), this quote is from 1972 % (when Vol II was published ?), which isn't particularly early. This % doesn't seem the sort of thing to get wrong! If someone wants to do % the checking and put it in (and re-BibTeX and re-check the page % breaks :-), please feel free. %% \begin{quote} %% ``{\em The various systems of combinatory logic are presented in this %% book as abstract obs systems. It was mentioned in \S{}~1 that any %% such system can be represented as a concrete syntactical system, and %% that this can be done mechanically. Nevertheless it seems expedient %% to give such a representation explicitly for two reasons: in the first %% place there is at present an almost universal insistence on such a %% representation; in the second place the discussion of certain %% philosophical questions is made somewhat easier by having a specific %% representation before us.}'' %% \begin{flushright} %% Haskell B.~Curry {\em et al.}\\ %% in {\em Combinatory Logic}, Vol.~II, page 8 \cite{curry-etal:volII}. %% \end{flushright} %% \end{quote} \noindent In this chapter, we describe the low-level lexical structure of \Haskell{}. Most of the details may be skipped in a first reading of the report. \subsection{Notational Conventions} \label{notational-conventions} These notational conventions are used for presenting syntax: \[\ba{cl} "[pattern]" & \tr{optional} \\ "\{pattern\}" & \tr{zero or more repetitions} \\ "(pattern)" & \tr{grouping} \\ "pat_1 | pat_2" & \tr{choice} \\ "pat_{\langle{}pat'\rangle{}}" & \tr{difference---elements generated by "pat"} \\ & \tr{except those generated by "pat'"} \\ "@fibonacci@" & \tr{terminal syntax in typewriter font} \ea\] Because the syntax in this section describes {\em lexical} syntax, all whitespace is expressed explicitly; there is no implicit space between juxtaposed symbols. BNF-like syntax is used throughout, with productions having the form: @@@ nonterm -> alt_1 | alt_2 | ... | alt_n @@@ Care must be taken in distinguishing metalogical syntax such as "|" and "[...]" from concrete terminal syntax (given in typewriter font) such as @|@ and @[...]@, although usually the context makes the distinction clear. \Haskell{} uses the Unicode \cite{unicode} character set. \index{Unicode character set} However, source programs are currently biased toward the ASCII character set \index{ASCII character set} used in earlier versions of \Haskell{}. % Removed Sept 02 % Haskell uses a pre-processor to convert non-Unicode character sets into % Unicode. This pre-processor converts all characters to Unicode and % uses the escape sequence @\u@"hhhh", where the @"h"@ are hex digits, % to denote escaped Unicode characters. Since this translation occurs % before the program is compiled, escaped Unicode characters may appear in % identifiers and any other place in the program. This syntax depends on properties of the Unicode characters as defined by the Unicode consortium. \Haskell{} compilers are expected to make use of new versions of Unicode as they are made available. \subsection{Lexical Program Structure} \label{lexemes} \label{whitespace} \input{syntax-lexical} Lexical analysis should use the ``maximal munch'' rule: at each point, the longest possible lexeme satisfying the "lexeme" production is read. \index{maximal munch rule} % using a context-independent deterministic lexical analysis % (i.e.~no lookahead beyond the current character is required). % Not so -- consider the input "F. 9. 0o 0x 9.0e+f", which % should lex as "F . 9 . 0 o 0 x 9.0 e + f" but that needs up % to 2 additional characters of lookahead. So, although @case@ is a reserved word, @cases@ is not. Similarly, although @=@ is reserved, @==@ and @~=@ are not. Any kind of "whitespace" is also a proper delimiter for lexemes. Characters not in the category "ANY" are not valid in \Haskell{} programs and should result in a lexing error. \subsection{Comments} Comments\index{comment} are valid whitespace. An ordinary comment\index{comment!end-of-line} begins with a sequence of two or more consecutive dashes (e.g. @--@) and extends to the following newline. {\em The sequence of dashes must not form part of a legal lexeme.} For example, ``@-->@'' or ``@|--@'' do {\em not} begin a comment, because both of these are legal lexemes; however ``@--foo@'' does start a comment. A nested comment\index{comment!nested} begins with ``@{-@'' and ends with ``@-}@''. No legal lexeme starts with ``@{-@''; hence, for example, ``@{---@'' starts a nested comment despite the trailing dashes. The comment itself is not lexically analysed. Instead, the first unmatched occurrence of the string ``@-}@'' terminates the nested comment. Nested comments may be nested to any depth: any occurrence of the string ``@{-@'' within the nested comment starts a new nested comment, terminated by ``@-}@''. Within a nested comment, each ``@{-@'' is matched by a corresponding occurrence of ``@-}@''. In an ordinary comment, the character sequences ``@{-@'' and ``@-}@'' have no special significance, and, in a nested comment, a sequence of dashes has no special significance. Nested comments are also used for compiler pragmas, as explained in Chapter~\ref{pragmas}. If some code is commented out using a nested comment, then any occurrence of @{-@ or @-}@ within a string or within an end-of-line comment in that code will interfere with the nested comments. \subsection{Identifiers and Operators}\index{identifier}\index{operator} \label{ids} @@@ varid -> (small \{small | large | digit | @'@ \})_{\langle{}reservedid\rangle{}} conid -> large \{small | large | digit | @'@ \} reservedid -> @case@ | @class@ | @data@ | @default@ | @deriving@ | @do@ | @else@ | @if@ | @import@ | @in@ | @infix@ | @infixl@ | @infixr@ | @instance@ | @let@ | @module@ | @newtype@ | @of@ | @then@ | @type@ | @where@ | @_@ @@@ \indexsyn{varid}% \indexsyn{conid}% \indexsyn{reservedid}% An identifier consists of a letter followed by zero or more letters, digits, underscores, and single quotes. Identifiers are lexically distinguished into two namespaces (Section~\ref{namespaces}): those that begin with a lower-case letter (variable identifiers) and those that begin with an upper-case letter (constructor identifiers). Identifiers are case sensitive: @name@, @naMe@, and @Name@ are three distinct identifiers (the first two are variable identifiers, the last is a constructor identifier). Underscore, ``@_@'', is treated as a lower-case letter, and can occur wherever a lower-case letter can. However, ``@_@'' all by itself is a reserved identifier, used as wild card in patterns. Compilers that offer warnings for unused identifiers are encouraged to suppress such warnings for identifiers beginning with underscore. This allows programmers to use ``@_foo@'' for a parameter that they expect to be unused. @@@ varsym -> ( symbol \{symbol | @:@\} )_{\langle{}reservedop | dashes\rangle{}} consym -> (@:@ \{symbol | @:@\})_{\langle{}reservedop\rangle{}} reservedop -> @..@ | @:@ | @::@ | @=@ | @\@ | @|@ | @<-@ | @->@ | \verb+@@+ | @~@ | @=>@ @@@ \indexsyn{varsym}% \indexsyn{consym}% \indexsyn{reservedop}% {\em Operator symbols} \index{operator} are formed from one or more symbol characters, as defined above, and are lexically distinguished into two namespaces (Section~\ref{namespaces}): \begin{itemize} \item An operator symbol starting with a colon is a constructor. \item An operator symbol starting with any other character is an ordinary identifier. \end{itemize} Notice that a colon by itself, ``@:@'', is reserved solely for use as the Haskell list constructor; this makes its treatment uniform with other parts of list syntax, such as ``@[]@'' and ``@[a,b]@''. Other than the special syntax for prefix negation, all operators are infix, although each infix operator can be used in a {\em section}\index{section} to yield partially applied operators (see Section~\ref{sections}). All of the standard infix operators are just predefined symbols and may be rebound. In the remainder of the report six different kinds of names\index{namespaces} will be used: @@@ varid && (\tr{variables}) conid && (\tr{constructors}) tyvar -> varid & (\tr{type variables}) tycon -> conid & (\tr{type constructors}) tycls -> conid & (\tr{type classes}) modid -> conid & (\tr{modules}) @@@ \indexsyn{varid}% \indexsyn{conid}% \indexsyn{tyvar}% \indexsyn{tycon}% \indexsyn{tycls}% \indexsyn{modid}% Variables and type variables are represented by identifiers beginning with small letters, and the other four by identifiers beginning with capitals; also, variables and constructors have infix forms, the other four do not. Namespaces are also discussed in Section~\ref{namespaces}. \index{qualified name} A name may optionally be {\em qualified} in certain circumstances by prepending them with a module identifier. This applies to variable, constructor, type constructor and type class names, but not type variables or module names. Qualified names are discussed in detail in Chapter~\ref{modules}. @@@ qvarid -> [modid @.@] varid qconid -> [modid @.@] conid qtycon -> [modid @.@] tycon qtycls -> [modid @.@] tycls qvarsym -> [modid @.@] varsym qconsym -> [modid @.@] consym @@@ \indexsyn{qvarid}% \indexsyn{qconid}% \indexsyn{qtycon}% \indexsyn{qtycls}% \indexsyn{qvarsym}% \indexsyn{qconsym}% Since a qualified name is a lexeme, no spaces are allowed between the qualifier and the name. Sample lexical analyses are shown below. \[\bto{|l|l|} \hline This & Lexes as this \\ \hline @f.g@ & @f . g@ (three tokens) \\ @F.g@ & @F.g@ (qualified `g') \\ @f..@ & @f ..@ (two tokens) \\ @F..@ & @F..@ (qualified `.') \\ @F.@ & @F .@ (two tokens) \\ \hline\eto\] The qualifier does not change the syntactic treatment of a name; for example, @Prelude.+@ is an infix operator with the same fixity as the definition of @+@ in the Prelude (Section~\ref{fixity}). \subsection{Numeric Literals}\index{number!literal syntax} \label{lexemes-numeric} @@@ decimal -> digit\{digit\} octal -> octit\{octit\} hexadecimal -> hexit\{hexit\} @@@ \indexsyn{decimal}% \indexsyn{octal}% \indexsyn{hexadecimal}% @@@ integer -> decimal | @0o@ octal | @0O@ octal | @0x@ hexadecimal | @0X@ hexadecimal float -> decimal @.@ decimal [exponent] | decimal exponent exponent -> (@e@ | @E@) [@+@ | @-@] decimal @@@ \indexsyn{integer}% \indexsyn{float}% There are two distinct kinds of numeric literals: integer and floating. Integer literals may be given in decimal (the default), octal (prefixed by @0o@ or @0O@) or hexadecimal notation (prefixed by @0x@ or @0X@). Floating literals are always decimal. A floating literal must contain digits both before and after the decimal point; this ensures that a decimal point cannot be mistaken for another use of the dot character. Negative numeric literals are discussed in Section~\ref{operators}. The typing of numeric literals is discussed in Section~\ref{numeric-literals}. \subsection{Character and String Literals} \index{character!literal syntax} \index{string!literal syntax} \label{lexemes-char} @@@ char -> @'@ (graphic_{\langle{}@'@ | @\@\rangle{}} | space | escape_{\langle{}@\&@\rangle{}}) @'@ string -> @"@ \{graphic_{\langle{}@"@ | @\@\rangle{}} | space | escape | gap\} @"@ escape -> @\@ ( charesc | ascii | decimal | @o@ octal | @x@ hexadecimal ) charesc -> @a@ | @b@ | @f@ | @n@ | @r@ | @t@ | @v@ | @\@ | @"@ | @'@ | @&@ ascii -> @^@cntrl | @NUL@ | @SOH@ | @STX@ | @ETX@ | @EOT@ | @ENQ@ | @ACK@ | @BEL@ | @BS@ | @HT@ | @LF@ | @VT@ | @FF@ | @CR@ | @SO@ | @SI@ | @DLE@ | @DC1@ | @DC2@ | @DC3@ | @DC4@ | @NAK@ | @SYN@ | @ETB@ | @CAN@ | @EM@ | @SUB@ | @ESC@ | @FS@ | @GS@ | @RS@ | @US@ | @SP@ | @DEL@ cntrl -> ascLarge | @@ | @[@ | @\@ | @]@ | @^@ | @_@ gap -> @\@ whitechar \{whitechar\} @\@ @@@ \indexsyn{char}% \indexsyn{string}% \indexsyn{escape}% \indexsyn{charesc}% \indexsyn{ascii}% \indexsyn{cntrl}% \indexsyn{gap}% \index{\\a@@{\tt {\char'134}a}}% \index{\\b@@{\tt {\char'134}b}}% \index{\\f@@{\tt {\char'134}f}}% \index{\\n@@{\tt {\char'134}n}}% \index{\\r@@{\tt {\char'134}r}}% \index{\\t@@{\tt {\char'134}t}}% \index{\\v@@{\tt {\char'134}v}}% \index{\\\&@@{\tt {\char'134}\&}}% Character literals are written between single quotes, as in @'a'@, and strings between double quotes, as in @"Hello"@. Escape codes may be used in characters and strings to represent special characters. Note that a single quote~@'@ may be used in a string, but must be escaped in a character; similarly, a double quote~@"@ may be used in a character, but must be escaped in a string. @\@ must always be escaped. The category "charesc" also includes portable representations for the characters ``alert'' (@\a@), ``backspace'' (@\b@), ``form feed'' (@\f@), ``new line'' (@\n@), ``carriage return'' (@\r@), ``horizontal tab'' (@\t@), and ``vertical tab'' (@\v@). Escape characters for the Unicode\index{Unicode character set} character set, including control characters such as @\^X@, are also provided. Numeric escapes such as @\137@ are used to designate the character with decimal representation 137; octal (e.g.~@\o137@) and hexadecimal (e.g.~@\x37@) representations are also allowed. % Numeric escapes that are out-of-range of the Unicode standard % (16 bits) are an error. Consistent with the ``maximal munch'' rule, \index{maximal munch rule} numeric escape characters in strings consist of all consecutive digits and may be of arbitrary length. Similarly, the one ambiguous ASCII escape code, @"\SOH"@, is parsed as a string of length 1. The escape character @\&@ is provided as a ``null character'' to allow strings such as @"\137\&9"@ and @"\SO\&H"@ to be constructed (both of length two). Thus @"\&"@ is equivalent to @""@ and the character @'\&'@\ is disallowed. Further equivalences of characters are defined in Section~\ref{characters}. A string may include a ``gap''---two backslants enclosing white characters---which is ignored. This allows one to write long strings on more than one line by writing a backslant at the end of one line and at the start of the next. For example, \bprog @ "Here is a backslant \\ as well as \137, \ \a numeric escape character, and \^X, a control character." @ \eprogNoSkip String literals are actually abbreviations for lists of characters (see Section~\ref{lists}). \subsection{Layout}\index{layout} \label{lexemes-layout} \Haskell{} permits the omission of the braces and semicolons used in several grammar productions, by using {\em layout} to convey the same information. This allows both layout-sensitive and layout-insensitive styles of coding, which can be freely mixed within one program. Because layout is not required, \Haskell{} programs can be straightforwardly produced by other programs. % without worrying about deeply nested layout difficulties. The effect of layout on the meaning of a Haskell program can be completely specified by adding braces and semicolons in places determined by the layout. The meaning of this augmented program is now layout insensitive. Informally stated, the braces and semicolons are inserted as follows. The layout (or ``off-side'') rule\index{off-side rule} takes effect whenever the open brace is omitted after the keyword @where@, @let@, @do@, or @of@. When this happens, the indentation of the next lexeme (whether or not on a new line) is remembered and the omitted open brace is inserted (the whitespace preceding the lexeme may include comments). For each subsequent line, if it contains only whitespace or is indented more, then the previous item is continued (nothing is inserted); if it is indented the same amount, then a new item begins (a semicolon is inserted); and if it is indented less, then the layout list ends (a close brace is inserted). If the indentation of the non-brace lexeme immediately following a @where@, @let@, @do@ or @of@ is less than or equal to the current indentation level, then instead of starting a layout, an empty list ``@{}@'' is inserted, and layout processing occurs for the current level (i.e. insert a semicolon or close brace). A close brace is also inserted whenever the syntactic category containing the layout list ends; that is, if an illegal lexeme is encountered at a point where a close brace would be legal, a close brace is inserted. The layout rule matches only those open braces that it has inserted; an explicit open brace must be matched by an explicit close brace. Within these explicit open braces, {\em no} layout processing is performed for constructs outside the braces, even if a line is indented to the left of an earlier implicit open brace. Section~\ref{layout} gives a more precise definition of the layout rules. Given these rules, a single newline may actually terminate several layout lists. Also, these rules permit: \bprog @ f x = let a = 1; b = 2 g y = exp2 in exp1 @ \eprog making @a@, @b@ and @g@ all part of the same layout list. As an example, Figure~\ref{layout-before} shows a (somewhat contrived) module and Figure~\ref{layout-after} shows the result of applying the layout rule to it. Note in particular: (a)~the line beginning @}};pop@, where the termination of the previous line invokes three applications of the layout rule, corresponding to the depth (3) of the nested @where@ clauses, (b)~the close braces in the @where@ clause nested within the tuple and @case@ expression, inserted because the end of the tuple was detected, and (c)~the close brace at the very end, inserted because of the column 0 indentation of the end-of-file token. \begin{figure} \outlinec{\small @ module AStack( Stack, push, pop, top, size ) where data Stack a = Empty | MkStack a (Stack a) push :: a -> Stack a -> Stack a push x s = MkStack x s size :: Stack a -> Int size s = length (stkToLst s) where stkToLst Empty = [] stkToLst (MkStack x s) = x:xs where xs = stkToLst s pop :: Stack a -> (a, Stack a) pop (MkStack x s) = (x, case s of r -> i r where i x = x) -- (pop Empty) is an error top :: Stack a -> a top (MkStack x s) = x -- (top Empty) is an error @ } %**

Figure 1

\ecaption{A sample program} \label{layout-before} \outlinec{\small @ module AStack( Stack, push, pop, top, size ) where {data Stack a = Empty | MkStack a (Stack a) ;push :: a -> Stack a -> Stack a ;push x s = MkStack x s ;size :: Stack a -> Int ;size s = length (stkToLst s) where {stkToLst Empty = [] ;stkToLst (MkStack x s) = x:xs where {xs = stkToLst s }};pop :: Stack a -> (a, Stack a) ;pop (MkStack x s) = (x, case s of {r -> i r where {i x = x}}) -- (pop Empty) is an error ;top :: Stack a -> a ;top (MkStack x s) = x -- (top Empty) is an error } @ } %**

Figure 2

\ecaption{Sample program with layout expanded} \label{layout-after} \end{figure} %**~footer % Local Variables: % mode: latex % End: haskell98-report-20080907/report/index-extra.verb0000644000175000017500000001216111345221573021065 0ustar marcotmarcot% "see XXX" and "see also YYY" index entries % % collected here and inserted at the END of the report % so that those index entries will always appear LAST % ------------------------------------------------------------------- % but first some ... % % NOTES ON INDEXING: by Will Partain (partain@@dcs.glasgow.ac.uk) % Paul Hudak did the initial selection of index entries for the report % (version 1.0); I haven't changed that, really. I did the automatic % indexing of the code in the prelude (Appendix A), and the % plug-and-chug indexing of the syntax non-terminals. % The important thing is consistency! Here's what I've done -- my % model has been the index for the LaTeX manual. This doesn't mean % that there aren't plenty of shortcomings. % % 1) I always index the singular form, i.e., "file", not "files"; % "expression", not "expressions". % % 2) The tricky part is how to index things that could come under % several possible titles. Here's an example and how I handled it. % Let's say we have several index entries for "list expression", % "conditional expression", and "case expression". % % * we want each index entry to appear under exactly one name % % * we want other likely/interesting entries to at least be % cross-referenced. % % So: % % * put each entry under the straightforward un-reordered thing; % in the example, "list expression", "case expression", etc. % % * under "expression" (a likely place for someone to look), have: % % expression % case, {\em see} case expression % conditional, {\em see} conditional expression % list, {\em see} list expression % ------------------------------------------------------------------- % \index{application!function|see{function application}} \index{application!operator|see{operator application}} \index{binding!function|see{function binding}} \index{binding!pattern|see{pattern binding}} \index{binding!simple pattern|see{simple pattern binding}} \index{character set!ASCII|see{ASCII character set}} \index{character set!transparent|see{transparent character set}} \index{datatype!abstract|see{abstract datatype}} \index{datatype!algebraic|see{algebraic datatype}} \index{datatype!declaration|see{{\tt data} declaration}} \index{datatype!recursive|see{recursive datatype}} \index{datatype!renaming|see{{\tt newtype} declaration}} \index{declaration!datatype|see{{\tt data} declaration}} \index{declaration!class|see{class declaration}} \index{declaration!instance|see{instance declaration}} \index{declaration!default|see{{\tt default} declaration}} \index{declaration!import|see{import declaration}} \index{declaration!fixity|see{fixity declaration}} \index{environment!class|see{class environment}} \index{environment!type|see{type environment}} \index{expression!type|see{type expression}} \index{expression!conditional|see{conditional expression}} \index{expression!unit|see{unit expression}} \index{expression!let|see{let expression}} \index{expression!case|see{case expression}} \index{expression!simple case|see{simple case expression}} \index{""@@-pattern@@{\tt {\char'100}}|see{as-pattern}} \index{_@@{\tt {\char'137}}|see{wildcard pattern}} \index{pattern!""@@-pattern@@{\tt {\char'100}}|see{as-pattern}} \index{pattern!_@@{\tt {\char'137}}|see{wildcard pattern}} \index{pattern!constructed|see{constructed pattern}} \index{pattern!integer|see{integer literal pattern}} \index{pattern!floating|see{floating literal pattern}} \index{pattern!linear|see{linear pattern}} \index{pattern!n+k@@"n@+@k"|see{"n@+@k" pattern}} \index{pattern!irrefutable|see{irrefutable pattern}} \index{pattern!refutable|see{refutable pattern}} \index{semantics!formal|see{formal semantics}} \index{string!transparent|see{transparent string}} \index{type!ambiguous|see{ambiguous type}} \index{type!monomorphic|see{monomorphic type}} \index{type!principal|see{principal type}} \index{type!trivial|see{trivial type}} \index{type!numeric|see{numeric type}} \index{type!function|see{function type}} \index{type!constructed|see{constructed type}} \index{type!tuple|see{tuple type}} \index{type!list|see{list type}} \index{type renaming|see{{\tt newtype} declaration}} \index{type signature!for an expression|see{expression type-signature}} % \index{(aaa)@@{\tt ()}|see{trivial type and unit expression}}% \index{-@@{\tt -}|hseealso{negation}} \index{+@@{\tt +}|hseealso{"n@+@k" pattern}} \index{\\@@{\tt {\char'134}}|see{lambda abstraction}} \index{~@@{\tt {\char'176}}|see{irrefutable pattern}} \index{derived instance|hseealso{instance declaration}} \index{if-then-else expression|see{conditional expression}} \index{instance declaration|hseealso{derived instance}} \index{layout|hseealso{off-side rule}} \index{off-side rule|hseealso{layout}} \index{method|see{class method}} \index{overloaded pattern|see{pattern-matching}} \index{precedence|hseealso{fixity}} \index{section|hseealso{operator application}} \index{signature|see{type signature}} \index{standard prelude|hseealso{{\tt Prelude}}} \index{synonym|see{type synonym}} \index{type class|see{class}} \index{type synonym|hseealso{datatype}} \index{unit datatype|see{trivial type}} \index{name!qualified|see{qualified name}} \index{name!special|see{special name}} haskell98-report-20080907/report/directory.verb0000644000175000017500000001670611345221573020652 0ustar marcotmarcot%**The Haskell 98 Library Report: Directory functions %**~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}. @get(set)Permissions@, @doesFile(Directory)Exist@, and @getModificationTime@ may fail with: @isPermissionError@ if the user is not permitted to access the appropriate information; or @isDoesNotExistError@ if the file/directory does not exist. The @setPermissions@ computation may also fail with: @isPermissionError@ if the user is not permitted to change the permission for the specified file or directory; or @isDoesNotExistError@ if the file/directory does not exist. % Duplicates the first case above, and would require % extensive consistency checking throughout. KH % The @doesFileExist@ and @doesDirectoryExist@ computations % may also fail with @isPermissionError@ if some part of the path % to the file/directory cannot be searched. %**~footer haskell98-report-20080907/report/Makefile0000644000175000017500000001733711345221573017427 0ustar marcotmarcot# Makefile for the Haskell Report # read the README file before you start! # # Target 'jfp' copies stuff into $(JFP_DIR) for the JFP book # you need to do the same in the libraries directory ########################################## # What to make if you type 'make' default: haskell.ps html # Begin by saying # touch haskell.idx ######################################### # 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 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 # EXPAND = c:/cygwin/bin/expand ######################################### # Files ######################################### RELEASE_DIR = ../haskell98-revised JFP_DIR = ../jfp-release PARTS = preface-jfp.tex $(PARTS_NO_PREFACE) PARTS_NO_PREFACE = iso-chars.tex \ intro.tex lexemes.tex exps.tex \ decls.tex modules.tex basic.tex io-13.tex \ derived.tex \ index-extra.tex index-intro.tex layout.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 = syntax-lexical.tex syntax-iso.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 PRELUDE = Prelude.tex PreludeList.tex PreludeText.tex PreludeIO.tex LIBPARTS = lib-array.tex lib-intro.tex lib-io.tex lib-num.tex lib-os.tex lib-text.tex \ lib-index-intro.tex lib-posix.tex LIBS = LibMonadicIO.tex LibStdIO.tex LibIOError.tex LibReadTextIO.tex LibWriteTextIO.tex \ LibSystem.tex LibDirectory.tex LibCPUTime.tex LibTime.tex LibUserInterrupt.tex \ LibRatio.tex LibArray.tex LibComplex.tex LibText.tex \ LibIO.tex LibIx.tex LibPosix.tex ######################################### # Main targets ######################################### # The normally formatted report -- 2 sided, one-up haskell.verb: plain_haskell.verb -cp plain_haskell.verb haskell.verb haskell.tex: haskell.verb $(EXPAND) < $< | $(VERBATIM) >$@ haskell.dvi: haskell.tex ${PARTS} $(SYNTAX) ${PRELUDE} # I have no idea why run_tex is run twice. SLPJ html: index.html ${PARTS} ${SYNTAX} ${PRELUDE} -mkdir haskell98-report-html $(RUN_TEX) $(RUN_TEX) $(RUN_INDEX) cp index.html *.gif haskell98-report-html haskell.dvi: haskell.tex haskell.ind ${PARTS} $(SYNTAX) ${PRELUDE} ${CODE} ${HEADERS} # remove this rule if you don't have "makeindex" haskell.ind: haskell.idx $(MAKEINDEX) -i -t haskell.ilg < haskell.idx > haskell.ind haskell.ps : haskell.dvi dvips haskell.dvi -o haskell.ps # Can't use pdflatex because of eps inclusion release: haskell.ps html ps2pdf haskell.ps gzip < haskell.ps > $(RELEASE_DIR)/haskell.ps.gz cp haskell.pdf $(RELEASE_DIR)/haskell.pdf cp -r haskell98-report-html $(RELEASE_DIR) tar cvf - haskell98-report-html | gzip > $(RELEASE_DIR)/haskell98-report-html.tar.gz cp h98-revised.html $(RELEASE_DIR)/index.html cp haskell98-bugs.html h98.gif $(RELEASE_DIR) cp haskell98-revised-bugs.html h98.gif $(RELEASE_DIR) publish-pdf: report.pdf gzip < report.pdf > y:Haskell/haskell98-report/report.pdf.gz ######################################### # Generic stuff ######################################### veryclean: clean $(RM) *~ clean: $(RM) *.dvi *.log *.aux *.ilg *.blg *.toc ${PARTS} $(SYNTAX) \ haskell.tex haskell.ps haskell.pdf *.o lex.yy.c haskell98-report-html/* cp haskell.ind haskell.ind.two-sided echo "Don't delete the Prelude*.tex files" echo "Not everyone has \"perl\" to re-make them" ######################################### # Suffix rules ######################################### .SUFFIXES: .hi .hs .verb .tex .dvi .verb.tex: $(EXPAND) < $< | $(VERBATIM) | ../tools/subsection >$@ # The 'subsection' part changes section -> chapter for the book style .hs.verb: $(EXPAND) < $< | $(SPLITPGM) >$@ %.tex: %.hs $(EXPAND) < $< | $(SPLITPGM) | $(VERBATIM) >$@ .hi.tex: $(EXPAND) < $< | $(SPLITPGM) | $(VERBATIM) >$@ .tex.dvi: $(LATEX) $< # ----------------------------------------------------------- # Out of date stuff # ----------------------------------------------------------- # Report as formatted for SIGPLAN -- 2 sided, 2-up, odd pages on left. # This is a bit horrible. But almost nobody should need to do this. KH sigplan_haskell.dvi: sigplan_haskell.verb sigplan_article.sty \ haskell.tex haskell.ind \ ${PARTS} $(SYNTAX) ${PRELUDE} cp sigplan_article.sty article.sty cp sigplan_haskell.verb haskell.verb -make haskell.dvi cp plain_haskell.verb haskell.verb sigplan_haskell-libraries.dvi: sigplan_haskell-libraries.tex haskell-libraries.ind ${LIBPARTS} ${LIBS} haskell-libraries.dvi: haskell-libraries.tex haskell-libraries.ind ${LIBPARTS} ${LIBS} # ----------------------- END OF OLD SIGPLAN STUFF ----------------------------------- jfp: h98-book.tex preface-jfp.tex ${PARTS_NO_PREFACE} $(SYNTAX) ${PRELUDE} -mkdir $(JFP_DIR) for n in h98-book.tex preface-jfp.tex \ ${PARTS_NO_PREFACE} $(SYNTAX) ${PRELUDE} ; do \ ../tools/subsection < $$n > $(JFP_DIR)/$$n ; done cp classes.eps $(JFP_DIR) cp haskell.bbl $(JFP_DIR)/h98-book.bbl cp Makefile-jfp-book $(JFP_DIR)/Makefile # 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 haskell-2up.ps : haskell-2up.dvi dvips -t landscape -x 707 haskell-2up.dvi > haskell-2up.ps haskell-2up.dvi : haskellx.dvi -dvidvi '2:0(0in,0in),1(160mm,0in)' haskellx.dvi > haskell-2up.dvi haskellx.dvi : sigplan_haskell.dvi dviselect =4: haskell.dvi haskellx.dvi haskell-libraries-2up.ps : haskell-libraries-2up.dvi dvips -t landscape -x 707 haskell-libraries-2up.dvi > haskell-libraries-2up.ps haskell-libraries-2up.dvi : haskell-librariesx.dvi -dvidvi '2:0(0in,0in),1(160mm,0in)' haskell-librariesx.dvi > haskell-libraries-2up.dvi haskell-librariesx.dvi : sigplan_haskell-libraries.dvi dviselect =4: sigplan_haskell-libraries.dvi haskell-librariesx.dvi haskell98-report-20080907/report/derived.verb0000644000175000017500000004657011345221573020272 0ustar marcotmarcot% % $Header: /home/cvs/root/haskell-report/report/derived.verb,v 1.13 2003/04/08 08:18:19 simonpj Exp $ % % The paragraph describing the formats of standard representations might % be deleted, since the info is already in the Prelude. % Note that there is a difference in the way readsPrec and showsPrec are defined. % showsPrec is exact Haskell text, readsPrec uses an auxiliary function which % isn't quite Haskell. %**The Haskell 98 Report: Derived Instances %**~header \section{Specification of Derived Instances} \label{derived-appendix} \index{derived instance} A {\em derived instance} is an instance declaration that is generated automatically in conjunction with a @data@ or @newtype@ declaration. The body of a derived instance declaration is derived syntactically from the definition of the associated type. Derived instances are possible only for classes known to the compiler: those defined in either the Prelude or a standard library. In this chapter, we describe the derivation of classes defined by the Prelude. If "T" is an algebraic datatype declared by:\index{algebraic datatype} \[\ba{lcl} "@data @cx@ =>@ T u_1 ... u_k"&@=@&"K_1 t_{11} ... t_{1k_1} @|@ \cdots @|@ K_n t_{n1} ... t_{nk_n}"\\ & & "@deriving (@C_1@,@ ...@,@ C_m@)@" \ea\] (where "m\geq0" and the parentheses may be omitted if "m=1") then a derived instance declaration is possible for a class "C" if these conditions hold: \begin{enumerate} \item "C" is one of @Eq@, @Ord@, @Enum@, @Bounded@, @Show@, or @Read@. \item There is a context "cx'" such that "cx' \Rightarrow C t_{ij}" holds for each of the constituent types "t_{ij}". \item If "C" is @Bounded@, the type must be either an enumeration (all constructors must be nullary) or have only one constructor. \item If "C" is @Enum@, the type must be an enumeration. \item There must be no explicit instance declaration elsewhere in the program that makes "T u_1 ... u_k" an instance of "C". % or of any of "C"'s superclasses. \end{enumerate} For the purposes of derived instances, a @newtype@ declaration is treated as a @data@ declaration with a single constructor. If the @deriving@ form is present, an instance declaration is automatically generated for "T u_1 ... u_k" over each class "C_i". If the derived instance declaration is impossible for any of the "C_i" then a static error results. If no derived instances are required, the @deriving@ form may be omitted or the form @deriving ()@ may be used. % OLD: %If the @deriving@ form is omitted then instance %declarations are derived for the datatype in as many of the six %classes mentioned above as is possible; that is, no static error can occur. %Since datatypes may be recursive, the implied inclusion in %these classes may also be recursive, and the largest %possible set of derived instances is generated. For example, %\bprog %@@%@@ %data T1 a = C1 (T2 a) | Nil1 %data T2 a = C2 (T1 a) | Nil2 %@@%@@ %\eprog %Because the @deriving@ form is omitted, we would expect derived %instances for @Eq@ (for example). But @T1@ is in @Eq@ only if @T2@ %is, and @T2@ is in @Eq@ only if @T1@ is. The largest solution has %both types in @Eq@, and thus both derived instances are generated. Each derived instance declaration will have the form: \[ "@instance (@cx@, @cx'@) =>@ C_i (T u_1 ... u_k) @where@ @{@ d @}@" \] where "d" is derived automatically depending on "C_i" and the data type declaration for "T" (as will be described in the remainder of this section). %% Yale nuked this: %% The class assertions "C' u'" are constraints on "T"'s %% type variables that are inferred from the instance declarations of the %% constituent types "t_{ij}". For example, consider: %% \bprog %% @@ %% data T1 a = C1 (T2 a) deriving Eq %% data T2 a = C2 a deriving () %% @@ %% \eprog %% And consider these three different instances for @T2@ in @Eq@:\nopagebreak %% \bprog %% @@ %% instance Eq (T2 a) where (C2 x) == (C2 y) = True %% %% instance (Eq a) => Eq (T2 a) where (C2 x) == (C2 y) = x == y %% %% instance (Ord a) => Eq (T2 a) where (C2 x) == (C2 y) = x > y %% @@ %% \eprog %% The corresponding derived instances for @T1@ in @Eq@ are: %% \bprog %% @@ %% instance Eq (T1 a) where (C1 x) == (C1 y) = x == y %% %% instance (Eq a) => Eq (T1 a) where (C1 x) == (C1 y) = x == y %% %% instance (Ord a) => Eq (T1 a) where (C1 x) == (C1 y) = x == y %% @@ %% \eprog The context "cx'" is the smallest context satisfying point (2) above. For mutually recusive data types, the compiler may need to perform a fixpoint calculation to compute it. The remaining details of the derived instances for each of the derivable Prelude classes are now given. Free variables and constructors used in these translations always refer to entities defined by the @Prelude@. \subsection{Derived instances of @Eq@ and @Ord@} \indexdi{Eq} \indexdi{Ord} The class methods automatically introduced by derived instances of @Eq@ and @Ord@ are @(==)@, \indextt{==} @(/=)@, \indextt{/=} @compare@\indextt{compare}, @(<)@, \indextt{<} @(<=)@, \indextt{<=} @(>)@, \indextt{>} @(>=)@, \indextt{>=} @max@\indextt{max}, and @min@\indextt{min}. The latter seven operators are defined so as to compare their arguments lexicographically with respect to the constructor set given, with earlier constructors in the datatype declaration counting as smaller than later ones. For example, for the @Bool@ datatype, we have that @(True > False) == True@. Derived comparisons always traverse constructors from left to right. These examples illustrate this property: \bprog @ (1,undefined) == (2,undefined) @"\Rightarrow"@ False (undefined,1) == (undefined,2) @"\Rightarrow"@ @"\bot"@ @ \eprog All derived operations of class @Eq@ and @Ord@ are strict in both arguments. For example, "@False <= @\bot" is "\bot", even though @False@ is the first constructor of the @Bool@ type. \subsection{Derived instances of @Enum@} \indexdi{Enum} Derived instance declarations for the class @Enum@ are only possible for enumerations (data types with only nullary constructors). The nullary constructors are assumed to be numbered left-to-right with the indices 0 through $n-1\/$. The @succ@ and @pred@ operators give the successor and predecessor respectively of a value, under this numbering scheme. It is an error to apply @succ@ to the maximum element, or @pred@ to the minimum element. The @toEnum@ and @fromEnum@ operators map enumerated values to and from the @Int@ type; @toEnum@ raises a runtime error if the @Int@ argument is not the index of one of the constructors. The definitions of the remaining methods are \par {\small \bprog @ enumFrom x = enumFromTo x lastCon enumFromThen x y = enumFromThenTo x y bound where bound | fromEnum y >= fromEnum x = lastCon | otherwise = firstCon enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] enumFromThenTo x y z = map toEnum [fromEnum x, fromEnum y .. fromEnum z] @ \eprog } where @firstCon@ and @lastCon@ are respectively the first and last constructors listed in the @data@ declaration. For example, given the datatype: \bprog @ data Color = Red | Orange | Yellow | Green deriving (Enum) @ \eprog we would have: \bprog @ [Orange ..] == [Orange, Yellow, Green] fromEnum Yellow == 2 @ \eprog \subsection{Derived instances of @Bounded@} \indexdi{Bounded} The @Bounded@ class introduces the class methods @minBound@\indextt{maxBound} and @maxBound@\indextt{minBound}, which define the minimal and maximal elements of the type. For an enumeration, the first and last constructors listed in the @data@ declaration are the bounds. For a type with a single constructor, the constructor is applied to the bounds for the constituent types. For example, the following datatype: \bprog @ data Pair a b = Pair a b deriving Bounded @ \eprog would generate the following @Bounded@ instance: \bprog @ instance (Bounded a,Bounded b) => Bounded (Pair a b) where minBound = Pair minBound minBound maxBound = Pair maxBound maxBound @ \eprog \subsection{Derived instances of @Read@ and @Show@} \label{derived-text} \indexdi{Read} \indexdi{Show} The class methods automatically introduced by derived instances of @Read@ and @Show@ are @showsPrec@\indextt{showsPrec}, @readsPrec@\indextt{readsPrec}, @showList@\indextt{showList}, and @readList@\indextt{readList}. They are used to coerce values into strings and parse strings into values. The function @showsPrec d x r@ accepts a precedence level @d@ (a number from @0@ to @11@), a value @x@, and a string @r@. It returns a string representing @x@ concatenated to @r@. @showsPrec@ satisfies the law: \[ "@showsPrec d x r ++ s == showsPrec d x (r ++ s)@" \] The representation will be enclosed in parentheses if the precedence of the top-level constructor in @x@ is less than @d@. Thus, if @d@ is @0@ then the result is never surrounded in parentheses; if @d@ is @11@ it is always surrounded in parentheses, unless it is an atomic expression (recall that function application has precedence @10@). The extra parameter @r@ is essential if tree-like structures are to be printed in linear time rather than time quadratic in the size of the tree. The function @readsPrec d s@ accepts a precedence level @d@ (a number from @0@ to @10@) and a string @s@, and attempts to parse a value from the front of the string, returning a list of (parsed value, remaining string) pairs. If there is no successful parse, the returned list is empty. Parsing of an un-parenthesised infix operator application succeeds only if the precedence of the operator is greater than or equal to @d@. It should be the case that \begin{center} @(x,"")@ is an element of @(readsPrec d (showsPrec d x ""))@ \end{center} That is, @readsPrec@ should be able to parse the string produced by @showsPrec@, and should deliver the value that @showsPrec@ started with. @showList@ and @readList@ allow lists of objects to be represented using non-standard denotations. This is especially useful for strings (lists of @Char@). %Because a string is a list of characters, @showsPrec@ of a string %such as @"abc"@ will result in the string %@"[@\fwq@a@\fwq @,@ \fwq@b@\fwq @,@ \fwq@c@\fwq @]"@. Because %@"\"abc\""@ would be a better representation, %the operators @showList@ %and @readList@ are provided in the class @Text@ for coercing {\em %lists} of values to and from strings. In particular, @showsPrec@ of a %string will yield the verbose form above, and @showList@ will yield %the compact version. For most other datatypes, @showList@ and %@readList@ will yield the same result as @showsPrec@ and @readsPrec@. %The instances of @Text@ for the standard types @Int@, @Integer@, @Float@, %@Double@, @Char@, lists, tuples, and rational and complex numbers are %defined in the %standard prelude (see Appendix~\ref{stdprelude}). %For characters and strings, the control characters that have special %representations (@\n@ etc.) are shown as such by @showsPrec@; %otherwise, ASCII mnemonics are used. %Non-ASCII characters are shown by decimal escapes. %Floating point numbers are represented by decimal numbers %of sufficient precision to guarantee @read . show@ is an identity %function. If $b$ is the floating-point radix and there are %$w$ base-$b$ digits in the floating-point significand, %the number of decimal digits required is %$d = \lceil w \log_{10} b \rceil + 1$ \cite{matula70}. %Numbers are shown in non-exponential format if this requires %only $d$ digits; otherwise, they are shown in exponential format, %with one digit before the decimal point. @readsPrec@ allows %an exponent to be unsigned or signed with @+@ or @-@; @showsPrec@ %shows a positive exponent without a sign. @readsPrec@ will parse any valid representation of the standard types apart from strings, for which only quoted strings are accepted, and other lists, for which only the bracketed form @[@\ldots@]@ is accepted. See Chapter~\ref{stdprelude} for full details. The result of @show@ is a syntactically correct \Haskell{} expression containing only constants, given the fixity declarations in force at the point where the type is declared. It contains only the constructor names defined in the data type, parentheses, and spaces. When labelled constructor fields are used, braces, commas, field names, and equal signs are also used. Parentheses are only added where needed, {\em ignoring associativity}. No line breaks are added. The result of @show@ is readable by @read@ if all component types are readable. (This is true for all instances defined in the Prelude but may not be true for user-defined instances.) Derived instances of @Read@ make the following assumptions, which derived instances of @Show@ obey: \begin{itemize} \item If the constructor is defined to be an infix operator, then the derived @Read@ instance will parse only infix applications of the constructor (not the prefix form). \item Associativity is not used to reduce the occurrence of parentheses, although precedence may be. For example, given \bprog @ infixr 4 :$ data T = Int :$ T | NT @ \eprog then: \begin{itemize} \item @show (1 :$ 2 :$ NT)@ produces the string @"1 :$ (2 :$ NT)"@. \item @read "1 :$ (2 :$ NT)"@ succeeds, with the obvious result. \item @read "1 :$ 2 :$ NT"@ fails. \end{itemize} \item If the constructor is defined using record syntax, the derived @Read@ will parse only the record-syntax form, and furthermore, the fields must be given in the same order as the original declaration. \item The derived @Read@ instance allows arbitrary Haskell whitespace between tokens of the input string. Extra parentheses are also allowed. \end{itemize} % However, the % derived @Read@ and @Show@ instances have the following properties: % \begin{itemize} % \item The result of @show@ is a syntactically correct \Haskell{} % expression containing only constants % given the fixity declarations in force at the point where % the type is declared. % \item The result of @show@ is readable by @read@ if all component % types are readable. (This is true for all instances defined in % the Prelude but may not be true for user-defined instances.) % \item The instance generated by @Read@ allows arbitrary whitespace % between tokens on the input string. Extra parentheses are also % allowed. % \item The result of @show@ contains only the constructor names defined % in the data type, parentheses, and spaces. When labelled % constructor fields are used, braces, commas, field names, and % equal signs are also used. % Spaces and parentheses are only added where % needed. No line breaks are added. % \item If a constructor is defined using labelled field syntax then the derived % @show@ for that constructor will use this same % syntax; the fields will be in the order declared in the % @data@ declaration. The derived @Read@ instance will use % this same syntax: all fields must be present and the declared order % must be maintained. % \item If a constructor is defined in the infix style, the derived @Show@ % instance will also use infix style. The derived @Read@ instance will % require that the constructor be infix. % \end{itemize} The derived @Read@ and @Show@ instances may be unsuitable for some uses. Some problems include: \begin{itemize} \item Circular structures cannot be printed or read by these instances. \item The printer loses shared substructure; the printed representation of an object may be much larger than necessary. \item The parsing techniques used by the reader are very inefficient; reading a large structure may be quite slow. \item There is no user control over the printing of types defined in the Prelude. For example, there is no way to change the formatting of floating point numbers. \end{itemize} %Figure~\ref{derived-text} gives the general form of a derived instance %of @Text@ for a user-defined datatype: %\[ %"@data@ cx @=>@ T u_1 ... u_k @=@ ... " %\] %@showsPrec@ and @readsPrec@ are as %in Appendices~\ref{showsPrec-spec} and \ref{readsPrec-spec}. The omitted %definitions of @readList@ and @showList@ in %Figure~\ref{standard-classes} (page~\pageref{standard-classes}) %are: %\bprog %@@ %readList:: ReadS [a] %readList r = [pr | ("[",s) <- lex r, % pr <- readl s ] % where readl s = [([],t) | ("]",t) <- lex s] ++ % [(x:xs,v) | (x,t) <- reads s, % (",",u) <- lex t, % (xs,v) <- readl u ] % %showList:: [a] -> ShowS %showList xs = showChar '[' . showl xs % where % showl [] = showChar ']' % showl (x:xs) = shows x . showChar ',' . showl xs %@@ %\eprog %\begin{figure} %\outline{ %@@ %instance (C, Text u1, ..., Text uk) => Text (T u1 ... uk) where % showsPrec = ... % readsPrec = ... %@@ %} %\caption{General form of a derived instance of @Text@} %\label{derived-text} %\end{figure} \subsection{An Example} As a complete example, consider a tree datatype:\nopagebreak %\bprog %@@ %data Tree a = Leaf a | Tree a :^: Tree a %@@ %\eprog\nopagebreak %Since there is no @deriving@ clause, this is shorthand for:\nopagebreak \bprog @ data Tree a = Leaf a | Tree a :^: Tree a deriving (Eq, Ord, Read, Show) @ \eprog Automatic derivation of instance declarations for @Bounded@ and @Enum@ are not possible, as @Tree@ is not an enumeration or single-constructor datatype. The complete instance declarations for @Tree@ are shown in Figure~\ref{tree-inst}, Note the implicit use of default class method \index{default class method} definitions---for example, only @<=@ is defined for @Ord@, with the other class methods (@<@, @>@, @>=@, @max@, and @min@) being defined by the defaults given in the class declaration shown in Figure~\ref{standard-classes} (page~\pageref{standard-classes}). \begin{figure}[tb] \outlinec{\small @ infixr 5 :^: data Tree a = Leaf a | Tree a :^: Tree a instance (Eq a) => Eq (Tree a) where Leaf m == Leaf n = m==n u:^:v == x:^:y = u==x && v==y _ == _ = False instance (Ord a) => Ord (Tree a) where Leaf m <= Leaf n = m<=n Leaf m <= x:^:y = True u:^:v <= Leaf n = False u:^:v <= x:^:y = u Show (Tree a) where showsPrec d (Leaf m) = showParen (d > app_prec) showStr where showStr = showString "Leaf " . showsPrec (app_prec+1) m showsPrec d (u :^: v) = showParen (d > up_prec) showStr where showStr = showsPrec (up_prec+1) u . showString " :^: " . showsPrec (up_prec+1) v -- Note: right-associativity of :^: ignored instance (Read a) => Read (Tree a) where readsPrec d r = readParen (d > up_prec) (\r -> [(u:^:v,w) | (u,s) <- readsPrec (up_prec+1) r, (":^:",t) <- lex s, (v,w) <- readsPrec (up_prec+1) t]) r ++ readParen (d > app_prec) (\r -> [(Leaf m,t) | ("Leaf",s) <- lex r, (m,t) <- readsPrec (app_prec+1) s]) r up_prec = 5 -- Precedence of :^: app_prec = 10 -- Application has precedence one more than -- the most tightly-binding operator @ } %**

Figure 8

\ecaption{Example of Derived Instances} \label{tree-inst} \end{figure} %**~footer haskell98-report-20080907/report/haskell98-bugs.html0000644000175000017500000024301511345221573021411 0ustar marcotmarcot Haskell 98: ERRATA
Haskell 98

No further changes should be made in this Errata.

Future changes are in The Revised Report bug list.


Errata in the Haskell 98 Language Report

All references are to the original Haskell 98 Report, dated 1 Feburary 1999.

  • Title page. Remove "[editor]" from after John Hughes.

  • Title page. Add the paragraph:

    "Copyright (c) Simon Peyton Jones.

    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, 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 a definition of the language Haskell 98."

  • [Aug 2001] Page 2, The Haskell Kernel. Replace the entire section with the following:

    "Haskell has adopted many of the convenient syntactic structures that have become popular in functional programming. In this Report, the meaning of such syntactic sugar is given by translation into simpler constructs. If these translations are applied exhaustively, the result is a program written in a small subset of Haskell that we call the Haskell kernel."

    "Although the kernel is not formally specified, it is essentially a slightly sugared variant of the lambda calculus with a straightforward denotational semantics. The translation of each syntactic structure into the kernel is given as the syntax is introduced. This modular design facilitates reasoning about Haskell programs and provides useful guidelines for implementors of the language."

    (The intent here is to avoid the common misconception that the kernel is a formally specified thing.)

  • [Sept 2001] Page 2, Section 1.4, Namespaces; and Page 7, Section 2.4, Identifiers and operators; and Page 15, Section 3.2, Variables, Constructors, Operators, and Literals. Remove the first paragraph (about operators), which does not really belong here, and item 2 of the list (which is related). Instead, amplify the remarks in Section 2.4 and 3.2. This is a presentational change only.

  • [Sept 2002] Page 4, Section 2.1, Notational conventions. Remove the second-last paragraph altogether, which begins "Haskell uses a pre-processor...". (No implementation does this, and the reference to escapes in identifiers is inconsistent with the lexical syntax.)

  • [Late Dec 2001] Page 5, Section 2.2, Lexical program structure; and Appendix B.2, p120. Replace the production for "comment" with:
      comment         -> dashes [ any_<symbol>  { any } \] newline
    
    (This ensures that "--+", for example, does not start a comment.)

  • [Dec 2001] Page 5, Section 2.2, Lexical program structure; and Appendix B.2, p120.
    • Change the production for lexeme to
       lexeme -> qvarid | qconid | qvarsym | qconsym | literal | special | reservedop | reservedid
      

    • [March 02] Change the productions for whitechar and newline to:
        whitechar -> newline | vertab | space | tab | uniWhite
        newline   -> return linefeed | return | linefeed | formfeed
      
      (This means that CR, LF, or CRLF (remember maximal munch), are all valid 'newline' separators, and the same sequence of characters should therefore work on any Haskell implementation.)

    • [March 02] Change the production for ANY to
        ANY -> graphic | whitechar
      
      (This is nicely similar to the production for "any".)

    • Change the production for uniDigit to
        uniDigit -> any Unicode decimal digit
      

    • Change the production for symbol to:
         symbol -> ascSymbol | uniSymbol< special | _ | : | " | ' >
      

    • Add return, linefeed, and uniWhite to the production for ANY.
    (These changes, and the next one, justify the productions for program which claims that a program is a sequence of lexemes and white space.)

  • [Feb 2002] Page 6, Section 2.2, Lexical program structure. In the first paragraph, delete the phrase ", using a context-independent deterministic lexical analysis (i.e.~no lookahead beyond the current character is required)".

    (The maximal munch rule is correct, but it's not true that it only takes one character of lookahead. Consider "F. 9. 0o 0x 9.0e+f", which should lex as "F . 9 . 0 o 0 x 9.0 e + f" but that needs up to two additional characters of lookahead.)

  • Page 7, Section 2.4, Identifiers and operators; and Appendix B.2, p121. Add dashes to reservedop in the exclusion set of the production for varsym. (This ensures that "--" and "---" are not legal lexemes.

  • [Nov 2001] Page 7, Section 2.4, Identifiers and operators; and Appendix B.2, p121.
    • Remove the productions for specialid and specialop
    • Delete the paragraph about specialid and specialop near the bottom of page 7 ("A few identifiers and operators..").

  • [Nov 2001] Page 8, Section 2.5, Numeric literals; and Appendix B.2, p121. Replace the production for "float" with:
       float       -> decimal . decimal [exponent]
                   |  decimal exponent
       exponent    -> (e | E) [+ | -] decimal
    
    (This change means that 20e3 is a floating-point literal. There is a corresponding change to the lexer on p114.)

  • Page 9, Section 2.4, Identifiers and operators; and Page 68, Section 5.5.1, Qualified names. Move the first paragraph of 5.5.1, and the following table, and the paragraph starting "The qualifier does not change...", to the end of Section 2.4. (These paragraphs deal with lexical matters, which do not belong in Chapter 5.)

  • Page 9, Section 2.6, Character and String Literals. In the production for "cntrl" replace "ASClarge" by "ascLarge".

  • [Nov 2001] Page 9, Section 2.6, Characters and String Literals; and Page 73, Section 6.1.2, Characters and strings
    • In Section 2.6, delete the last sentence of the third paragraph "Numeric escapes that are out of range...".

    • In Section 6.1.2, replace the first sentence of the section by

      "The character type Char is an enumeration whose values represent Unicode characters [10]." Similarly, remove the final clause "...in the range [0..2^16 - 1]".

    (This change removes the commitment to 16-bit Unicode. The result is that the Report is even vaguer than before about the range of Unicode that a compiler is obliged to accept, but this confusion is in large part Unicode's fault, and is not readily fixed in a revision of this nature.)

  • Page 10, Section 2.7, Layout. In the middle of the third paragraph, just before the sentence beginning "A close brace is also inserted...", add the following sentence:

    "If the indentation of the non-brace lexeme immediately following a where, let, do or of is less than or equal to the current indentation level, then instead of starting a layout, an empty list "{}" is inserted, and layout processing occurs for the current level (i.e. insert a semicolon or close brace)."

  • Page 11, Figures 1 and 2. In both figures the signature for size should be
      size :: Stack a -> Int
    

  • [July 2001] Page 12, Section 3, Expressions. Replace the last two sentences of the first paragrah of the section by:

    "Free variables and constructors used in these translations always refer to entities defined by the Prelude. For example, ``concatMap'' used in the translation of list comprehensions (Section 3.11) means the concatMap defined by the Prelude, regardless of what is in scope where the list comprehension is used."

    (Clarification only.)

  • [May 2002] Page 12, Section 3, Expressions; also Page 17, Section 3.5; also Page 128, Appendix B, Syntax. Add the following two extra productions for aexp:
    	|   '(' lexp(i) qop(l,i) ')'        left section
            |   '(' qop(r,i)<-> rexp(i) ')'        right section
    
    and change the othe right-section production to:
            |   '(' qop(a,i)<-> exp(i+1) ')'        right section
    
    (This brings the formal syntax into line with the words in Section 3.5. The grammar now follows the way that qfunlhs is defined. There is no ambiguity, because an exp(i+1) is not an lexp(i).)

    The exclusion of "-" from right sections is also new [May 2002]; it is necessary to prevent overlap with the unary-minus syntax.

  • [Aug 2001] Page 13, Section 3, Expressions. Remove Table 1, and the associated paragraph beginning "As an aid to understanding...". (The table causes more confusion than it clears up.)

  • [March 2002] Page 14, Section 3, Expressions. After the sample parses, add the following paragraphs:

    A note about parsing. Expressions that involve the interaction of fixities with the let/lambda meta-rule may be hard to parse. For example, the expression

      let x = True in x == x == True
    
    cannot possibly mean
      let x = True in (x == x == True)
    
    because (==) is a non-associative operator; so the expression must parse thus:
      (let x = True in (x == x)) == True
    
    However, implementations may well use a post-parsing pass to deal with fixities, so they may well incorrectly deliver the former parse. Programmers are advised to avoid constructs whose parsing involves an interaction of (lack of) associativity with the let/lambda meta-rule.

  • [Nov 2001] Page 13, Section 3 Expressions. Replace the curly braces by angle brackets, in the subscript of "aexp" in the last production of "aexp". Similarly, on Page 26, Section 3.15.3; and Page 128, Appendix B.4.

  • [Apr 2001] Page 14, Section 3.1, Errors. In the first sentence of the section, after "indistinguishable" add "by a Haskell program".

  • [Apr 2001] Page 15, Section 3.2, Variables, Constructors, Operators, and Literals. Remove the paragraph starting "Qualified names may only ...", and the following example, and the concluding paragraph starting "incorrectly uses a qualifier". (This is all covered in 2.4 and 5.5.1.)

  • [May 2002] Page 17, Section 3.5, Sections. Append the following to the paragraph beginning "Syntactic precedence rules apply to sections as follows."

    "As another example, the expression

      (let x = 10 in x +)
    
    is invalid because, by the let/lambda meta-rule (Section 3) the expression
      (let n = 10 in n + x)
    
    parses as
      (let n = 10 in (n + x))
    
    rather than
      ((let n = 10 in n) + x)
    
    "

  • [Oct 2001] Page 18, Section 3.7, Lists. After the sentence starting "The constructor ":" is reserved solely for list construction...", add the new sentence:

    "It is a right-associative operator, with precedence level 5 (Section 4.4.2)."

    (Otherwise this information is found only in the Prelude.)

  • [July 2001] Page 20, Section 3.10, Arithmetic sequences. In the second paragraph, in the sentence "For the type Integer, arithmetic sequences have the following meaning...", replace "type Integer" with "types Int and Integer". Remove Integer from the list in the paragraph following the bulletted list.

  • [Apr 2001] Page 21, Section 3.11, List Comprehensions; and Page 128.
    • In the production for "aexp", change the "n >= 0" to "n >= 1".
    • Remove the production for (empty qualifier)
    • In the translation box lower down the page, rewrite the translation so that it does not involve and empty list of qualifiers. (Unchanged semantics.)
    This change ensures that there is at least one qualifier in list comprehension, and no qualifier is empty. The translation lower down page 23 is then not utterly rigorous, because Q can be empty, and when it is there is no preceding comma, but I reckon it would make matters worse to "fix" it.

  • [March 2002] Page 22, Section 3.13, Case Expressions. To the end of the section, add the following paragraphs:

    A note about parsing. The (type-incorrect) expression

      case x of { (a,_) | let b = not a in b :: Bool -> a }
    
    is tricky to parse correctly. It has a single unambiguous parse, namely
      case x of { (a,b) | (let b = not a in b :: Bool) -> a }
    
    However, the phrase Bool -> a is syntactically valid as a type, and parsers with limited lookahead may incorrectly commit to this choice, and hence reject the program. Programmers are advised, therefore, to avoid guards that end with a type signature --- indeed that is why a "gd" contains an "exp^0" not an "exp".

  • [Apr 2001] Page 23, Section 3.14, Do Expressions; and Page 128, Appendix B.4, Context Free Syntax.
    • Change the production for stmts to read:
      	stmts -> stmt1 ... stmtn exp [;]	(n>=0)
      
    • Add ";" to the end of each of the four productions for stmt.
    That is, every list of statements must end in an expression, optionally followed by a semicolon.

  • [Aug 2001] Page 24, Section 3.15, Datatypes with Field Labels.. Add an example to illustrate the final point in para 2.

  • [Feb 2002] Page 25, Section 3.15.2, Construction Using Field Labels. At the end of the section add the sentence:

    The expression F {}, where F is a data constructor, is legal whether or not F was declared with record syntax, provided F has no strict fields; it denotes F _|_1 ... _|_n, where n is the arity of F.

    (This matches the dual for pattern matching, in Section 4.2.1.)

  • [Aug 2001] Page 26, Section 3.15.3, Updates Using Field Labels. In the translation box:
    • replace the first un-subscripted "C" by "C1", and the second by "Cj". (The "1" and "j" should be subscripts of course!)
    • Change "b" to "bs" in the "where..." part.

  • [Aug 2001] Page 28, Section 3.17.1, Patterns.. Give an example to illustrate an illegal non-linear pattern.

  • [Jan 2002] Page 29, Section 3.17.2, Informal Semantics of Case Expressions. Reword the entire numbered list giving the informal semantics, so that:
    • It is clearly classified by pattern.
    • The semantics of matching a newtype pattern against bottom is given.
    • A literal and n+k pattern may not diverge even if the value matched is bottom; it depends on the definition of == and >= respectively.

  • [Aug 2001] Page 31, Section 3.17.2, Informal Semantics of Case Expressions. Replace the example at the foot of Page 31, following the paragraph "The guard semantics...", with the following:
        f :: (Int,Int,Int) -> [Int] -> Int
        f ~(x,y,z) [a] | (a == y) = 1
    
    (The previous example use boolean and, which is non-strict in its second argument!)

  • [Apr 2001] Page 31,33, Figures 3 and 4, Semantics of Case Expressions. Replace "completely new variable" by "new variable" in these two figures. (Some clauses said "new" and some "completely new" which is misleadingly inconsistent.)

  • [Apr 2001] Page 33, Figure 4, Semantics of Case Expressions Part 2. In clause (r) replace "e0" by "v" throughout.

  • [Jan 2002] Page 33, Figure 4, Semantics of Case Expressions Part 2.
    • Insert new clause (r):
      	case _|_ of { K x1 ... xn -> e; _ -> e' } = _|_
      	where K is a data constructor of arity n
      
    • Rename old clause (r) as clause (s).
    • Use lambda instead of let in the new clause (s), so as to avoid the suggestion of polymorphism (just as in other clauses).
    • In the accompanying text, final paragaph, add clause (s) to the list of clauses that use lambda to avoid suggesting polymorphism.

  • [May 2002] Page 34, Section 4, Declarations and Bindings; and Page 44, Section 4.3.1, Class Declarations. In the production for class, replace
    	class [scontext =>] simpleclass [where decls]
    
    by
    	class [scontext =>] tycls tyvar [where decls]
    

  • [Sept 2001] Page 36, Section 4.1.2, Syntax of Types. First paragraph, last sentence. After "infix type constructors are not allowed", add "(other than (->))".

  • [Oct 2001] Page 38, Section 4.1.2, Algebraic Datatype Declarations. Replace the sentence "Although the tuple, list, and function types have special syntax, they are not different from user-defined types with equivalent functionality." with

    "These special syntactic forms always denote the built-in type constructors for functions, tuples, and lists, regardless of what is in scope. In a similar way, the prefix type constructors (->),, [], (), (,), and so on, always denote the built-in type constructors; they cannot be qualified, nor mentioned in import or export lists (Section 5). (Hence the special production, gtycon, above.)

    "Although the tuple and list types have special syntax, their semantics is the same as the equivalent user-defined algebraic data types."

    (This stuff is clarification only.)

  • Page 40, Section 4.2.1, Algebraic Datatype Declarations. In the bottom paragraph on the page, before "The context in the data declaration has no other effect whatsoever" add the following:

    "Pattern matching against ConsSet also gives rise to an Eq a constraint. For example:

      f (ConsSet a s) = a
    
    the function f has inferred type Eq a => Set a -> a."

  • Page 41, Section 4.2.1, subsection Labelled Fields. At the end of the subsection, add a new paragraph:

    "The pattern "F {}" matches any value built with constructor F, whether or not F was declared with record syntax."

  • [Nov 2001] Page 41, Section 4.2.1, subsection Strictness Flags. Add the following sentence at the end of the pargraph:

    "Lexically, "!" is an ordinary varsym not a reservedop; it has special significance only in the context of the argument types of a data declaration."

  • [Apr 2001] Page 42, Section 4.2.1, subsection Labelled Fields. Change "occurance" to "occurrence" in the translation box at the very end of the section.

  • [Late Dec 2001] Page 46, Section 4.3.2, Instance Declarations.
    • Remove the production for "qfunlhs".
    • Replace the first production for "idecl" by:
        idecl -> (funlhs | var) rhs
      
      (i.e. omitting the alternatives for "qvar" and "qfunlhs").
    • In the third paragraph from the bottom, delete the text starting "However, unlike other declarations, the name of the bound variable may be qualified..." and ending at "Hence the need for the qfunlhs and qvar left hand sides for an idecl.".
    • In place of the deleted sentences, add the following:

      "It is illegal to give a binding for a class method that is not in scope, but the name under which it is in scope is immaterial; in particular, it may be a qualified name. (This rule is identical to that used for subordinate names in export lists --- Section 5.2.) For example, this is legal, even though return is in scope only with the qualified name Monad.return.

        module A where
          import qualified Monad
      
          instance Monad.Monad T where
            return = ...
            (>>=)  = ...
      
      "
    • Make the same syntactic changes to the syntax in Appendix B.4.
    (This signficant change removes a wart from the language. Instead of requiring a qualified name on the LHS of an instance declaration if the method name is in scope in more than one way, the context is now used to disambiguate. This is compatible with the story for type signatures, Section 4.4.1.)

  • [Late Dec 2001] Page 49, Section 4.3.4, Ambiguous Types... In the third paragraph from the end of 4.3.4, replace "monotype" by "type".

  • Page 49, Section 4.3.4, Ambiguous Types... In the third paragraph from the end of Section 4.3.4, replace "...an ambiguous type variable is defaultable if at least one of its classes is a numeric class..." by "...an ambiguous type variable, v, is defaultable if v appears only in constraints of the form (C v), where C is a class, and if at least one of its classes is a numeric class...".

    The new phrase is "if v appears only in constraints of the form (C v) where C is a class". Without this condition the rest of the sentence does not make sense.

  • [Aug 2001] Page 51, Section 4.4.2, Fixity Declarations.
    • In the prodution for gendecl change digit to integer.
    • Make the same change in the syntax at the start of Section 4 and in Appendix B.
    • After "A fixity declaration gives the fixity and binding precedence of one or more operators." add the sentence "The integer in a fixity declaration must be in the range 0 to 9."
    (Previously, "digit" was used, and it isn't a lexeme.)

  • [Apr 2001] Page 53, Section 4.4.3. Replace "For example, these two function definitions are equivalent:", and the two lines of code that follow by:
    "For example, these three function definitions are all equivalent:
      plus x y z = x+y+z
      x `plus` y = \ z -> x+y+z
      (x `plus` y) z = x+y+z
    
    " (This change makes explicit that an infix operator with more than two arguments can have all of them on the LHS.)

  • [Apr 2001] Page 54, Section 4.4.3, subsection Function Bindings. In the first translation scheme ("The general binding form for functions..."), the xn should be xk (suitably subscripted in both cases!), and all three m subscripts should be n.

  • Page 57, Section 4.5.3, Context reduction errors. The example
          f :: (Monad m, Eq (m a)) => a -> m a -> Bool
          f x y = x == return y
    
    is wrong; it should read
          f x y = return x == y
    

  • [Sept 2001] Page 58, Section 4.5.5, Momomorphism. In the boxed text entitled "The monomorphism restriction", replace "The usual Hindley-Milner restriction on polymorphism is that only type variables free in the environment may be generalized" by

    "The usual Hindley-Milner restriction on polymorphism is that only type variables that do not occur free in the environment may be generalized."

    (The sense was backward before.)

  • [May 2001] Page 62, Section 5, Modules. In paragraph 4, add a footnote to the sentence "A multi-module Haskell program can be converted into a single-module program by ...", namely:

    "There are two minor exceptions to this statement. First, default declarations scope over a single module (Section 4.3.4). Second, Rule 2 of the monomorphism restriction (Section 4.5.5) is affected by module boundaries."

    This footnote qualifies the otherwise over-strong statement.

  • [Late Dec 2001] Page 63,64, Section 5.2, Export lists.
    • In the production for "export", replace "qcname" by "cname" (and similarly in Appendix B.4).
    • In the production for "qcname", replace "qcname" by "cname", "qvar" by "var", and "qcon" by "con". In Appendix B.4 delete the production for "qcname".
    • In the second bulleted item under point (2) of the numbered items, replace "qcname" by "c", throughout.
    • In point (2) of the numbered items, add the following:

      "In all cases, the (possibly-qualified) type constructor T must be in scope. The constructor and field names c_i in the second form are unqualified; one of these subordinate names is legal if and only if (a) it names a constructor or field of T, and (b) the constructor or field is in scope in the module body regardless of whether it is in scope under a qualified or unqualified name. For example, the following is legal

        module A( Mb.Maybe( Nothing, Just ) ) where
          import qualified Maybe as Mb
      
      "
    • Make a similar change to point (4).
    • In points (1)-(4), make it clear that the variable, type constructor, or class must be in scope.
    (These changes clarify the scope rules for export lists. Much email discussion during Dec 2001.)

  • [March 02] In point (2) delete the sentence "The qcnamei must not conatin duplications.". Make a similar change in point (4).

  • [Oct 2001, modified Nov 2002] Page 64, Section 5.2, Export declarations, numbered items 5 and 6. Replace both items with the following:

    The form "module M" names the set of all entities that are in scope with both an unqualified name "e" and a qualified name "M.e". This set may be empty. For example:

      module Queue( module Stack, enqueue, dequeue ) where
          import Stack
          ...
    
    "Here the module Queue uses the module name Stack in its export list to abbreviate all the entities imported from Stack.

    "A module can name its own local definitions in its export list using its own name in the `module M'' syntax, because a local declaration brings into scope both a qualified and unqualified name. For example:

      module Mod1( module Mod1, module Mod2 ) where
      import Mod2
      import Mod3
    
    "Here module Mod1 exports all local definitions as well as those imported from Mod2 but not those imported from Mod3." It is an error to use module M in an export list unless M is the module bearing the export list, or M is imported by at least one import declaration (qualified or unqualified).

  • [July 2001] Page 65, Section 5.2, Export declarations. Replace the two paragraphs and code fragment that the numbered list with the following:

    "It makes no difference to an importing module how an entity was exported. For example, a field name f from data type T may be exported individually (f, item (1) above); or as an explicitly-named member of its data type (T(f), item (2)); or as an implicitly-named member (T(..) item(2)); or by exporting an entire module (module M, item (5)).

    Exports lists are cumulative: the set of entities exported by an export list is the union of the entities exported by the individual items of the list.

    The unqualified names of the entities exported by a module must all be distinct (within their respective namespace). For example

      module A ( C.f, C.g, g, module B ) where   -- an invalid module
      import B(f)
      import qualified C(f,g)
      g = f True
    
    There are name clashes in the export list between C.g and g, and between module B and C.f (assuming B.f and C.f are different entities), even though there are no name clashes within module A itself.

  • [Feb 2002] Page 65, Section 5.3, Import Declarations, syntax; also page 125, Appendix B.4. In the second production for "import", namely "tycon [ [(..)] | (cname1, ..., cnamen)]" replace "n>=1" by "n>=0". (There is no need to require one or more constructors, and in hiding clauses it may be useful to hide the type constructor only.)

  • [Nov 2001] Page 65, Section 5.3, Import Declarations, last line. Before "Exactly which entities are to be imported..." add a new paragraph:

    "Lexically speaking, the terminal symbols "as", "qualified" and "hiding" are each a "varid" rather than a "reservedid". They have special significance only in the context of an import declaration; they may also be used as variables."

  • [July 2001] Page 65, Section 5.3, Import Declarations, last line. Start a new subsection "5.3.1 What is imported" before "Exactly which entities are to be imported...".

  • [July 2001] Page 66, Section 5.3, Import Declarations, numbered item 2. Delete the two sentences "The hiding clause only applies to unqualified names... A hiding clause has no effect....".

  • [Oct 2001] Page 66, Section 5.3, Import Declarations, numbered item 2. Add "It is an error to hide an entity that is not, in fact, exported by the imported module."

  • [July 2001] Page 66, Section 5.3.1, Qualified Import. [This section becomes 5.3.2.] Replace the first sentence with: "For each entity imported under the rules of Section 5.3.1 the top-level environment is extended. If the import declaration used the qualified keyword, only the qualified name of the entity is brought into scope. If the qualified keyword is omitted, then both the qualified and unqualified name of the entity is brought into scope. Section 5.5.1 describes qualified names in more detail."

  • Page 67, Section 5.3.2, Local aliases. The last example in the section should read:
    	import Foo as A(f)
    

  • [Aug 2001] Page 68, Section 5.5.1, Qualified names. Replace the second example in the first bullet by:
      module M where
        M.f x = ...			-- ILLEGAL
        g x = let M.y = x+1 in ...	-- ILLEGAL
    
    (This just clarifies that qualifiers aren't legal in local decls either.)

  • Page 69, Section 5.5.2, Name clashes. At the very end of the section, add the following clarification:

    "The name occurring in a type signature or fixity declarations is always unqualified, and unambiguously refers to another declaration in the same declaration list (except that the fixity declaration for a class method can occur at top level --- Section 4.4.2). For example, the following module is legal:

    	
      module F where
        sin :: Float -> Float
        sin x = (x::Float)
    
        f x = Prelude.sin (F.sin x)
    
    The local declaration for sin is legal, even though the Prelude function sin is implicitly in scope. The references to Prelude.sin and F.sin must both be qualified to make it unambigous which sin is meant. However, the unqualified name "sin" in the type signature in the first line of F unambiguously refers to the local declaration for sin."

  • [Nov 2001] Page 71, Section 5.6.1, The Prelude module. Replace the entire first paragraph of the section with:

    "The Prelude module is imported automatically into all modules as if by the statement `import Prelude', if and only if it is not imported with an explicit import declaration. This provision for explicit import allows entities defined in the Prelude to be selectively imported, just like those from any other module."

  • [May 2002] Page 71, Section 5.6.2, Shadowing Prelude Names. Replace the entire section with the following, which clarifies matters considerably compared to the original Haskell 98 Report. "
      module A( null, nonNull ) where
        import Prelude hiding( null ) 
        null, nonNull :: Int -> Bool
        null    x = x == 0
        nonNull x = not (null x)
    
    Module A redefines null, and contains an unqualified reference to null on the right hand side of nonNull. The latter would be ambiguous without the "hiding(null)" on the "import Prelude" statement. Every module that imports A unqualified, and then makes an unqualified reference to null must also resolve the ambiguous use of null just as A does. Thus there is little danger of accidentally shadowing Prelude names.

    "It is possible to construct and use a different module to serve in place of the Prelude. Other than the fact that it is implicitly imported, the Prelude is an ordinary Haskell module; it is special only in that some objects in the Prelude are referenced by special syntactic constructs. Redefining names used by the Prelude does not affect the meaning of these special constructs. For example, in

      module B where
        import Prelude()
        import MyPrelude
        f x = (x,x)
        g x = (,) x x
        h x = [x] ++ []
    
    the explicit import Prelude() declaration prevents the automatic import of Prelude, while the declaration import MyPrelude brings the non-standard prelude into scope. The special syntax for tuples (such as (x,x) and (,)) and lists (such as [x] and []) continues to refer to the tuples and lists defined by the standard Prelude; there is no way to redefine the meaning of [x], for example, in terms of a different implementation of lists. On the other hand, the use of ++ is not special syntax, so it refers to ++ imported from MyPrelude.

    "It is not possible, however, to hide instance declarations in the Prelude. For example, one cannot define a new instance for Show Char."

  • [Aug 2001] Page 74, Section 6.1.3, Lists. In the last sentence, after "Monad" add ", Functor". (The list type is an instance of Functor.)

  • [May 2001] Page 74, Section 6.1.4, Tuples. Replace the first paragraph of this section with:

    "Tuples are algebraic datatypes with special syntax, as defined in Section 3.8. Each tuple type has a single constructor. All tuples are instances of Eq, Ord, Bounded, Read, Show (provided, of course, that all their component types are).

    There is no upper bound on the size of a tuple, but some Haskell implementations may restrict the size of tuples, and limit the instances associated with larger tuples. However, every Haskell implementation must support tuples up to size 15, together with their instances for Eq, Ord, Bounded, Read, and Show. The Prelude and libraries define tuple functions such as zip for tuples up to a size of 7."

  • [Apr 2001] Page 74, Section 6.1.6, Function Types. Delete the sentence "Functions are an instance of the Show class but not Read".

  • [Aug 2001] Page 75, Section 6.1.7, The IO and IOError Types. In the second sentence, replace "Show" by "Functor". (IO is an instance of Functor, but not Show.)

  • [Apr 2001] Page 76, Section 6.3, Standard Haskell classes. There is a formatting error in the example. There should be a new line after "the declaration of Class Eq is:", and before the sentence beginning "This declaration gives default method declarations...".

  • [July 2001] Page 78, Section 6.3.2, The Ord Class. Redefine the default methods for max and min as follows:
        max x y | x <= y    =  y
                | otherwise =  x
        min x y | x <= y    =  x
                | otherwise =  y
    
    (This change aligns the report with the code given in the Appendix.)

  • [Apr 2001] Page 78, Section 6.3.3, The Read and Show Classes. After "The Read and Show classes are used to convert values to and from strings." add the sentence: "The Int argument to showsPrec and readsPrec gives the operator precedence of the enclosing context (see Appendix D.4)." (Clarification only.)

  • [May 2002] Page 79, Section 6.3.3, The Read and Show Classes. Add documentation for the function lex:

    "The function lex :: ReadS String, used by read, is also part of the Prelude. It reads a single lexeme from the input, discarding initial white space, and returning the characters that constitute the lexeme. If the input string contains only white space, lex returns a single successful ``lexeme'' consisting of the empty string. (Thus lex "" = [("","")].) If there is no legal lexeme at the beginning of the input string, lex fails (i.e. returns [])."

  • [Nov 2001] Page 79, Section 6.3.4, Class Enum; Page 19, Section 3.10 Arithmetic Sequences; and Appendix D.2, Derived instances of Enum.
    • Move the specification of the Int and Integer instances of Enum from 3.10 to 6.3.4.
    • Specify that, for bounded types, succ and pred should fail when applied to maxBound and minBound resp.
    • Specify that the enum functions on numeric types are strict.
    • Remove material from D.2 so that it describes only the derived instances.
    This change amounts to a fairly complete rewrite of 6.3.4, with a slightly tighter specification than before.

  • Page 80, Section 6.3.6, Class Monad. Right at the bottom of the page, replace "However, for IO, the fail method invokes error." by "For IO, the fail method raises a user exception in the IO monad (see Section 7.3)."

  • [Aug 2001] Page 82, Section 6.4, Numbers.In paragraph 2 of 6.4, replace "Rational library" with "Ratio library".

  • [July 2001] Page 83, Section 6.4.2, Arithmetic and number-theoretic operations. After "The quod, rem, div, and mod class methods satisfy these laws" add "if y is non-zero".

  • [Apr 2001] Page 84, Section 6.4, Fig 7; and bottom of page 86, Section 6.4.6.
        fromRealFrac :: (RealFrac a, Fractional b) => a -> b
    
    should be replaced by
        realToFrac :: (Real a, Fractional b) => a -> b
    

  • [Late Dec 2001] Page 84, Section 6.4.2, gcd. In the final paragraph of 6.4.2, replace "gcd x y is the greatest integer that divides both x and y" by "gcd x y is the greatest (positive) integer that divides both x and y. gcd 0 0 raises a runtime error".

    (The "(positive)" clarifies a slightly ambiguous point, while the specification for gcd 0 0 remains controversial. There was a lot of email on the Haskell mailing list in Dec 2001 about the latter point.)

  • Page 88, Section 7.1, Standard I/O functions. In the section "Input functions" replace "the IOError value associated with end-of-file is defined in a library" by "a predicate isEOFError that identifies this exception is defined in the IO library".

  • [May 2002] Page 88, Section 7.1, Standard I/O functions. In the section "Input functions",
    • Change "Both getChar and getLine raise an exception on end-of-file;" to "The getChar operation raises an exception on end-of-file;".
    • After that sentence, add the further sentence "The getLine operation raises an exception under the same circumstances as hGetLine, defined the IO library."
    (This change goes along with a more precise description of the behaviour of hGetLine.)

  • [Sept 2002] Page 88, Section 7.1, Standard I/O functions. Remove the paragraph "By default, these input functions echo to standard output." (There was a lot of discussion on the Haskell mailing list on this point, in Sept 2002. The conclusion was that the sentence should go, though it would have been better to craft something more detailed.)

  • Page 90, Section 7.3, Exception handling in the IO monad. After the first paragraph give the following type signature:
      userError :: String -> IOError
    
    Also add an index entry for userError on this page. (These changes are purely presentational.)

  • [Apr 2001] Page 90, Section 7.3, Exception handling in the IO monad. After the above signature for userError, add the following: "The fail method of the IO instance of the Monad class (Section 6.3.6) raises a userError, thus:
      instance Monad IO where 
        ...bindings for return, (>>=), (>>)
    
        fail s = ioError (userError s)
    
    "

  • [Dec 2001] Page 91, Appendix A, Standard Prelude.
    • Add the following paragraph to clarify the status of the default-method definitions.

      "The default method definitions, given with class declarations, constitute a specification only of the default method. They do not constitute a specification of the meaning of the method in all instances. To take one particular example, the default method for enumFrom in class Enum will not work properly for types whose range exceeds that of Int (because fromEnum cannot map all values in the type to distinct Int values)."

    • Add the following paragraph, to say why some functions have an unexpectedly restricted type:

      "To reduce the occurrence of unexpected ambiguity errors, and to improve efficiency, a number of commonly-used functions over lists use the Int type rather than using a more general numeric type, such as Integral a or Num a. These functions are: take, drop, index, length, splitAt, and replicate. The more general versions are given in the List library, with the prefix "generic"; for example genericLength."

  • [Oct 2001] Page 93, Appendix A, Standard Prelude. Replace the fixity declaration for (:) by the following comments:
    -- The (:) operator is built-in syntax, and cannot legally be given
    -- a fixtity declaration; but its fixity is given by:
    --   infixr 5  :
    

  • [Nov 2001] Page 94, Appendix A, Standard Prelude, class Enum.
    • Before the default methods add:
      	-- NOTE: these default methods only make sense for types
      	-- 	 that map injectively into Int using fromEnum
      	--	 and toEnum.
      
    • After the default method for enumFromTo add
        enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..]
      

  • Page 95, Appendix A, Standard Prelude, class Floating. Add asin, acos, atan to the comment giving the list of minimal complete definitions.

  • [Dec 2001] Page 100, Appendix A, instance Bounded Char.
    • Replace the definition of maxBound by
        maxBound = primUnicodeMaxChar
      
    • Import UnicodePrims( primUnicodeMaxChar ) at the top of the module.
    (This avoids making explicit what the largest character is.)

  • [Apr 2001] Page 101, Appendix A, instance Monad IO. Replace the definition of fail in instance Monad IO by
        fail s = ioError (userError s)
    

  • Page 102, Appendix A, comments immediately before instance Enum Float. Replace "1.0" by "0.95".

  • [Aug 2001] Page 101, Appendix A, instance of Monad IO. Delete defintion for >> . (The default definition will do.)

  • [Oct 2002] Page 103, Appendix A.1, line 19. In the definition of numericFromThenTo replace "n' > n" by "n' >= n". So the definition now reads:
    numericEnumFromThenTo n n' m = takeWhile p (numericEnumFromThen n n')
                                 where
                                   p | n' >= n   = (<= m + (n'-n)/2)
                                     | otherwise = (>= m + (n'-n)/2)
    
    (This change makes the code agree with the last bullet in (the revised version of) 6.3.4.)

  • [Apr 2001] Page 105, Appendix A.1, line 11. In the module header for PreludeList replace "Sum" by "sum".

  • Page 105, Appendix A.1 (PreludeList), line 19. Correct the type of map to
      map :: (a -> b) -> [a] -> [b]
    

  • Page 106, definition of (!!). Replace the definition of (!!) with the following:
        -- List index (subscript) operator, 0-origin
        (!!)                :: [a] -> Int -> a
        xs     !! n | n < 0 =  error "Prelude.!!: negative index"
        []     !! _         =  error "Prelude.!!: index too large"
        (x:_)  !! 0         =  x
        (_:xs) !! n         =  xs !! (n-1)
    
    (The original version had the property that ([] !! -100) reported "index too large".)

  • [Apr 2001] Page 107, definition of scanl1 and scanr1. Replace the definitions of scanl1 and scanr1 with these:
    scanl            :: (a -> b -> a) -> a -> [b] -> [a]
    scanl f q xs     =  q : (case xs of
                                []   -> []
                                x:xs -> scanl f (f q x) xs)
    
    scanl1           :: (a -> a -> a) -> [a] -> [a]
    scanl1 f (x:xs)  =  scanl f x xs
    scanl1 _ []      =  []
    
    scanr1          :: (a -> a -> a) -> [a] -> [a]
    scanr1 f []     =  []
    scanr1 f [x]    =  [x]
    scanr1 f (x:xs) =  f x q : qs
                       where qs@(q:_) = scanr1 f xs 
    
    The effect is to make both functions defined on the empty list.

  • [Apr 2001] Page 108, definition of take, drop, and splitAt. Replace the definitions of take, drop, and splitAt with these:
        take                   :: Int -> [a] -> [a]
        take n _      | n <= 0 =  []
        take _ []              =  []
        take n (x:xs)          =  x : take (n-1) xs
        
        drop                   :: Int -> [a] -> [a]
        drop n xs     | n <= 0 =  xs
        drop _ []              =  []
        drop n (_:xs)          =  drop (n-1) xs
    
        splitAt                  :: Int -> [a] -> ([a],[a])
        splitAt n xs             =  (take n xs, drop n xs)
    
    The effect is that all three functions are defined on negative arguments. This is a semantic change.

  • [Jan 2002] Page 112, header for PreludeText. Remove show from the export list, and re-insert it as an exported operation of class Show.

  • [Nov 2001] Page 114, definition of lex. Change the line that currently reads
        lexFracExp s = [("",s)]
    
    to read instead
        lexFracExp s = lexExp s
    
    (This change allows 10e3 to be a single lexeme; c.f. the lexical change on page 7.)

  • [May 2001; showsPrec corrected Sept 2001] Page 115, instances Show Int and Read Int. Replace the instances for Show Int and Read Int with
        instance  Show Int  where
    	showsPrec n = showsPrec n . toInteger
    	    -- Converting to Integer avoids
    	    -- possible difficulty with minInt
        
        instance  Read Int  where
          readsPrec p r = [(fromInteger i, t) | (i,t) <- readsPrec p r]
    	    -- Reading at the Integer type avoids
    	    -- possible difficulty with minInt
    
    The previous definitions (which are simply specifications, remember) failed on minInt.

  • [July 2002] Page 115, instances Read Float and Read Double. These two instance declarations should read:
        instance  Read Float  where
    	readsPrec p         = readSigned readFloat
        
        instance  Read Double  where
    	readsPrec p         = readSigned readFloat
    
    (Adding the 'readSigned' call.)

  • [Late Dec 2001] Page 118, defn of interact. Replace the definition of interact with the following.
        interact    ::  (String -> String) -> IO ()
        -- The hSetBuffering ensures the expected interactive behaviour
        interact f  =  do hSetBuffering stdin  NoBuffering
                          hSetBuffering stdout NoBuffering
                          s <- getContents
                          putStr (f s)
    

  • [Dec 2001] Page 122, Appendix B.3, Layout.

    • Replace the first dashed item in the first bullet item by:

      "If a let, where, do,, or of keyword is not followed by the lexeme {, the token "{n}" is inserted after the keyword, where "n" is the indentation of the next lexeme if there is one, or "0" if the end of file has been reached."

      (This addresses the question of end of file just after a where.)

    • Replace the third dashed item in the first bullet item by:

      "Where the start of a token is preceded only by white space on same line, this token is preceded by "<n>" where "n" is the indentation of the token, provided that it is not, as a consequence of the first two rules, preceded by "{n}".

      (This addresses the question of empty lines (no layout token) and string-gap tokens (no layout token in the middle of them). I have added a clarifying example as well.)

  • [Nov 2001] Page 122, Appendix B.3, Layout. In the paragraph following the bullets, add the sentence: "The characters "newline", "return", "linefeed", and "formfeed", all start a new line."

  • [Sept 2002] Page 122, Appendix B.3, Layout. After the sentence "For the purposes of the layout rule, Unicode characters in a source program are considered to be of the same, fixed, width as an ASCII character." add the clarifying sentence

    "However, to avoid visual confusion, programmers should avoid writing programs in which the meaning of implicit layout depends on the width of non-space characters."

  • [Oct 2001] Page 123, Appendix B.3, Layout. In the first line of the definition of L, replace "if parse-error(t)" by "if m /= 0 and parse-error(t)". This checks that the implicitly-added close brace matches an implicit open brace.

  • [Late Dec 2001] Page 122,123, Appendix B.3, Layout.
    • On p122, replace "L tokens [0]" by "L tokens []".

    • Replace the layout equations on p123 with the following:

      L (<n>:ts) (m:ms) = ; : (L ts (m:ms)) if m = n
      = } : (L (<n>:ts) ms) if n < m
      L (<n>:ts) ms = L ts ms
      L ({n}:ts) (m:ms) = { : (L ts (n:m:ms)) if n > m (Note 1)
      L ({n}:ts) [] = { : (L ts [n]) if n > 0 (Note 1)
      L ({n}:ts) ms = { : } : (L (<n>:ts) ms) (Note 2)
      L (}:ts) (0:ms) = } : (L ts ms) (Note 3)
      L (}:ts) ms = parse-error (Note 3)
      L ({:ts) ms = { : (L ts (0:ms)) (Note 4)
      L (t:ts) (m:ms) = } : (L (t:ts) ms) if m /= 0 and parse-error(t)
      (Note 5)
      L (t:ts) ms = t : (L ts ms)
      L [] [] = []
      L [] (m:ms) = } : L [] ms if m /=0 (Note 6)

    • Renumber the notes correspondingly.
    (These changes deal with various corner cases, such as empty where clauses; order the equations so that they clearly deal completely with the tokens "<n>", "{n}", "(", and "}" before dealing with the general case; and ensure that the tokens "<n>" and "{n}" are never passed to "parse-error".)

  • [Aug 2001] Page 124, Appendix B.3, Layout. Near the end of the sub-section, delete from "Another place where..." to the end of the sub-section. (Note 5 covers the top-level case.)

  • [May 2002] Page 124, Appendix B.3, Layout To the very end of B.3, append the following:

    "The parse-error rule is hard to implement in its full generality, because doing so involves fixities. For example, the expression

      do a == b == c
    
    has a single unambiguous (albeit probably type-incorrect) parse, namely
      (do { a == b }) == c
    
    because (==) is non-associative. Programmers are therefore advised to avoid writing code that requires the parser to insert a closing brace in such situations."

  • [Sept 2002] Page 130, Appendix C, Literate comments. Move Appendix C (Literate comments) into Appendix B (Syntax), just after the section on Layout. (This structure makes more sense when the report appears as a book.)

  • [Oct 2001] Page 130, Appendix C, Literate comments. In paragraph 2, replace "The program text is recovered by taking only those lines beginning with ">", and deleting the first character of each of those lines" with

    "The program text is recovered by taking only those lines beginning with ">", and replacing the leading ">" with a space."

  • [Late Dec 2001] Page 130, Appendix C, Literate comments. Final paragraph. After the phrase "all other lines are comment." add the sentence:

    "More precisely:

    • Program code begins on the first line following a line that begins \begin{code}.
    • Program code ends just before a subsequent line that begins \end{code} (ignoring string literals, of course)."

  • [May 2001] Page 132, Appendix D, Specification of Derived Instances. In numbered item 3, replace ``(all constructors must by nullary)'' with ``(all constructors must be nullary)''.

  • [Jan 2002] Page 132, Appendix D, Specification of Derived Instances. Mention that computing the context for the derived instance declaration may involve a fixpoint calculation.

  • [Feb 2002, modified Oct 2002] Page 133, Appendix D.1, Derived Instances of Eq and Ord. Add the final sentence:

    All derived operations of class Eq and Ord are strict in both arguments. For example, False <= _|_ is _|_ , even though False is the first constructor of the Bool type.

  • [Oct 2002] Page 134, Appendix D.4, Derived instances of Read and Show.
    • In para 2, replace "10" by "11". Thus "(a number from 0 to 11)".
    • In para 3 replace "...if d is 10 it is always surrounded in parentheses, unless it is an atomic expression." by: "if d is 11 it is always surrounded in parentheses, unless it is an atomic expression (recall that function application has precedence 10)."

  • [June 2001] Page 134, Appendix D.4, Derived instances of Read and Show. In the displayed equation starting fst (head (...)) == x, replace "r" by the empty string, resulting in the following:

    (x,"") is an element of (readsPrec d (showsPrec d x ""))

    (The old, stronger, equation is simply false.)

  • [Oct 2002] Page 135, Appendix D.4, Derived instances of Read and Show. In para 1, replace "readsPrec will parse any valid representation of the standard types apart from lists, for which only the bracketed form [...] is accepted." by:

    "readsPrec will parse any valid representation of the standard types apart from strings, for which only quoted strings are accepted, and other lists, for which only the bracketed form [...] is accepted."

  • [May 2002] Page 135, Appendix D.4, Derived instances of Read and Show. Replace the paragraph starting "A precise description of the derived...", and all the following bullets, with the following (the main change is to make Show ignore associativity, so that a simple derived parser will terminate even on left-recursive inputs):

    The result of show is a syntactically correct Haskell expression containing only constants, given the fixity declarations in force at the point where the type is declared. It contains only the constructor names defined in the data type, parentheses, and spaces. When labelled constructor fields are used, braces, commas, field names, and equal signs are also used. Parentheses are only added where needed, ignoring associativity. No line breaks are added. The result of show is readable by read if all component types are readable. (This is true for all instances defined in the Prelude but may not be true for user-defined instances.)

    Derived instances of Read make the following assumptions, which derived instances of Show obey:

    • If the constructor is defined to be an infix operator, then the derived Read instance will parse only infix applications of the constructor (not the prefix form).
    • Associativity is not used to reduce the occurrence of parentheses, although precedence may be. For example, given
        infixr :$
        data T = Int :$ T  |  NT
      
      then:
      • show (1 :$ 2 :$ NT) produces the string "1 :$ (2 :$ NT)".
      • read "1 :$ (2 :$ NT)" succeeds, with the obvious result.
      • read "1 :$ 2 :$ NT" fails.
    • If the constructor is defined using record syntax, the derived Read will parse only the record-syntax form, and furthermore, the fields must be given in the same order as the original declaration.
    • The derived Read instance allows arbitrary Haskell whitespace between tokens of the input string. Extra parenthese are also allowed."

  • [Aug 2001] Page 138, Appendix E, Compiler pragmas.
    • Change inline to INLINE.
    • Change notInline to NOINLINE.
    • Change specialize to SPECIALIZE.
    • Remove the optional digit from the INLINE pragma, and replace the first para of E.1 by:

      "The INLINE pragma instructs the compiler to inline the specified variables at their use sites. Compilers will often automatically inline simple expressions. This may be prevented by the NOINLINE pragma."

    • Delete the whole of E.3.
    (These changes simplify the pramga story, and bring it into line with what is usually implemented.)

  • [Apr 2001] Page 141, Bibliograpy. Citation [4] should read "JR Hindley".

  • Page 141, Bibliograpy. The library report citation [8] is out of date. It should read: "Simon Peyton Jones and John Hughes (editors), Standard Libraries for the Haskell 98 Programming Language, 1 February 1999".

  • Page 147, Index. Remove the entry for "monad comprehension".

  • [Apr 2001] Index of the Haskell 98 Prelude (HTML version only)
    • Remove Eval as a superclass of Num
    • Correct type of seq to seq :: a -> b -> b.
    • Correct type of getLine to IO String
    • [Jan 2002] Correct type of map and add entry for fmap.
    • [Jan 2002] Add entry for filter
    • [Feb 2002] The equations given for foldl and foldr were wrong. They should be
          foldl (+) 0 [a,b,c] = ((0+a)+b)+c
          foldr (+) 0 [a,b,c] = a+(b+(c+0))
      
      Furthermore, the function name was misspelled in the equation for foldr1.

Errata in the Haskell 98 Library Report

  • Title page. Remove "[editor]" from after John Hughes.

  • Title page. Add the paragraph:

    "Copyright (c) Simon Peyton Jones.

    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, 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 a definition of the Haskell 98 libraries."

  • [Apr 2001] Page 5, Section 2.1, Library Ratio. Replace the definition of recip on line 3 by the following
        recip (x:%y)        =  y % x
    
    The effect of this change is to use the "smart constructor", %, instead doing it by hand. In particular, an error will be raised if y is zero.

  • [Oct 2002] Page 5, Section 2.1, Library Ratio. Add the following definitions to the instance for Enum.
        succ x           =  x+1
        pred x           =  x-1
    
    (This makes succ/pred behave in the same way for Ratio as they do for Float and Double. Of course, it is still highly dubious having these fractional types in Enum at all, but that is another matter.)

  • [July 2002] Page 5, Section 2.1, Library Ratio. Modify the Read and Show instances of Ratio as follows:
      instance  (Read a, Integral a)  => Read (Ratio a)  where
        readsPrec p  =  readParen (p > prec)
                                  (\r -> [(x%y,u) | (x,s)   <- readsPrec (prec+1) r,
                                                    ("%",t) <- lex s,
                                                    (y,u)   <- readsPrec (prec+1) t ])
    
      instance  (Integral a)  => Show (Ratio a)  where
        showsPrec p (x:%y)  =  showParen (p > prec)
                                   (showsPrec (prec+1) x . 
    			        showString " % " . 
    				showsPrec (prec+1) y)
    
    
    (It is important that the recursive calls carry the appropriate precedence.)

  • [Nov 2001] Page 9, Numeric library.
    • Add showIntAtBase, showHex, and showOct to the export list.
    • Add documentation for these functions.
    • In the body of the module, replace the definition of showInt with the following:
        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
      
      (This siginficant change extends the Numeric library so that it can show octal and hexadecimal numbers, just as it can already read them.)

  • [Nov 2001] Page 13, Section 4.1, Numeric library.
    • Add specifications for the functions exported by the Numeric library.

    • In formatRealFloat, replace the entire case alternative starting FFFixed with the following:
                FFFixed ->
                  case decs of
                     Nothing 	-- Always prints a decimal point
                       | e > 0     -> take e (ds ++ repeat '0')
                                      ++ '.' : mk0 (drop e ds)
                       | otherwise -> "0." ++ mk0 (replicate (-e) '0' ++ ds)
                    
                     Just dec ->  -- Print decimal point iff dec > 0
                       let dec' = max dec 0 in
                       if e >= 0 then
                         let (ei, is') = roundTo base (dec' + e) is
                             (ls, rs)  = splitAt (e+ei) 
                                                    (map intToDigit is')
                         in  mk0 ls ++ mkdot0 rs
                       else
                         let (ei, is') = roundTo base dec' 
                                                 (replicate (-e) 0 ++ is)
                             d : ds = map intToDigit 
                                          (if ei > 0 then is' else 0:is')
                         in  d : mkdot0 ds
                  where   
                    mk0 "" = "0"        -- Print 0.34, not .34
                    mk0 s  = s  
          
                    mkdot0 "" = ""       -- Print 34, not 34.
                    mkdot0 s  = '.' : s  -- when the format specifies no
      			           -- digits after the decimal point
      
      (This fixes an infinite loop.)

    • In the definition of k in floatToDigits replace "fromInt e" by "fromIntegral e". (fromInt no longer exists.)
    • Last line of code for floatToDigits, replace "toInt" by "fromIntegral". (toInt no longer exists.)

  • [Sept 2001] Page 16, Section 4, Numeric library. In the definition of readFloat, after "... (k,t) <- readExp s]" add
        ++ [ (0/0, t) | ("NaN",t)      <- lex r]
        ++ [ (1/0, t) | ("Infinity",t) <- lex r]
    
    (This makes readFloat able to read "Infinity" and "NaN", which formatRealFloat can produce.)

  • [May 2002] Page 9, Section 4, Numeric library. In the type for readFloat replace "(RealFloat a)" by "(RealFrace a)". (This makes it possible to read a Rational number using readFloat.)

  • Page 17, Section 5, first text line. Replace "continuous" by "contiguous".

  • [May 2001] Page 17, Section 5, Indexing operations. Add the following equation to the laws listed just before Section 5.1:
      map index (range (l,u)) == [0..rangeSize (l,u)]
    
    This documents an invariant that was previously only implicit.

  • [Oct 2001] Page 17, Section 5, Indexing operations. This significant item makes rangeSize into a method of Ix rather than a free-standing declaration. Though this change is visible to the programmer, all existing Haskell 98 programs will continue to work.
    • Page 17, Section 5, Indexing operations, boxed text. Replace the Ix class declaration, and the type signature for rangeSize with:
        class Ord a => Ix a where
          range     :: (a,a) -> [a]
          index     :: (a,a) -> a -> Int
          inRange   :: (a,a) -> a -> Bool
          rangeSize :: (a,a) -> Int
      
    • Section 5.2, pages 19, line 3. Replace the Ix class declaration, and the rangeSize declaration, with:
        class Ord a => Ix a where
          range     :: (a,a) -> [a]
          index     :: (a,a) -> a -> Int
          inRange   :: (a,a) -> a -> Bool
          rangeSize :: (a,a) -> Int
      
          rangeSize b@(l,h) | null (range b) = 0
                            | otherwise      = index b h + 1 
      	-- NB: replacing "null (range b)" by  "not (l <= h)"
      	-- fails if the bounds are tuples.  For example,
      	-- 	(1,2) <= (2,1)
      	-- but the range is nevertheless empty
      	--	range ((1,2),(2,1)) = []
      
      (Note: the comment has changed too; it was misleading before.)
    (Note: an earlier proposal to remove the Ord superclass was rejected.)

  • [July 2001] Page 17, Section 5.1, Derived instances of Ix. Replace the first paragraph with the following:

    "It is possible to derive an instance of Ix automatically, using a deriving clause on a data declaration (Section 4.3.3 of the Language Report). Such derived instance declarations for the class Ix are only possible for enumerations (i.e. datatypes having only nullary constructors) and single-constructor datatypes, whose constituent types are instances of Ix. A Haskell implementation must provide Ix instances for tuples up to at least size 15."

    [This change just clarifies, and propagates the "instances up to size 15" change from Section 6.1.6 of the Language Report.]

  • Page 22, Section 6.3; and Page 23, Fig 3: Replace "map" by "fmap" (two occurrences in 6.3, one in Fig 3).

  • [Dec 2001] Page 23, Figure 3. In the definition of diag, delete the guard ``| l==l' && u==u'''. (The original intent was presumably to check for a square array, but simply makes the definition recursive and hence divergent.)

  • [July 2002] Page 24, Section 6.4, Library Array. Use the following Read and Show instances for Array:
      instance  (Ix a, Show a, Show b) => Show (Array a b)  where
        showsPrec p a = showParen (p > arrPrec) (
                        showString "array " .
                        showsPrec (arrPrec+1) (bounds a) . showChar ' ' .
                        showsPrec (arrPrec+1) (assocs a)                  )
    
      instance  (Ix a, Read a, Read b) => Read (Array a b)  where
        readsPrec p = readParen (p > arrPrec)
               (\r -> [ (array b as, u) 
                      | ("array",s) <- lex r,
                        (b,t)       <- readsPrec (arrPrec+1) s,
                        (as,u)      <- readsPrec (arrPrec+1) t ])
    
      -- Precedence of the 'array' function is that of application itself
      arrPrec = 10
    
    (It is important that the recursive calls use the appropriate precedence.)

  • Page 29, Section 7.2. Add a new bullet for nub. Add an index entry for nub.

  • Page 29, Section 7.2, second bullet. Introduce a new bullet just before "union is list union".

  • [July 2002] Page 29, Section 7.2, third bullet. Remove the first intersect in the displayed equation.

  • Page 30, Section 7.3. Add a bullet for insert.

  • [May 2001] Page 30, Section 7.4, unfoldr. Replace the first line-and-a-half paragraph with:

    "The unfoldr function is a `dual' to foldr: while foldr reduces a list to a summary value, unfoldr builds a list from a seed value. For example:

      iterate f == unfoldr (\x -> Just (x, f x))
    
    In some cases, unfoldr can undo a foldr operation:"

    (Followed by the existing displayed equation.)

  • [Feb 2002] Page 31, Section 7.6, The "By" operations. Change the defintion of nub to:
      nub        :: (Eq a) => [a] -> [a]
      nub []     =  []
      nub (x:xs) =  x : nub (filter (\y -> not (x == y)) xs)
    
    (This eliminates a conflict with the definition in Section 7.8.)

  • [Apr 2001] Page 31, Section 7.7, Library List. Add a new subsection "The zip operations" to document zip4, zip5, etc.

  • [Dec 2001] Page 33, Section 7.8, Library List. Replace the definition of unionBy by the following:
        unionBy eq xs ys =  xs ++ deleteFirstsBy eq (nubBy eq ys) xs
    
    (This is a simpler definition to understand.)

  • [Apr 2001] Page 34, Section 7.8, Library List. Replace the definition of partition by
       partition               :: (a -> Bool) -> [a] -> ([a],[a])
       partition p xs          =  (filter p xs, filter (not . p) xs)
    
    This simply makes it agree with the definition on page 30 (Section 7.3).

  • [Apr 2001] Page 35, Section 7.8. Replace the definitions of maximumBy and minimumBy by the following
        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
        
        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
    
    NOTE: this is a semantic change, but it makes the definitions consistent with the other "By" functions, and with the signatures given on page 28.

  • [Dec 2001] Page 41, Sections 9, Character utilities. Add an explanation of lexLitChar, and an example.

  • [Jan 2002] Page 43, Sections 9.1, Library Char. Add isLatin1 to the list of variables in the type signature for "character-testing operations".

  • [May 2002] Page 45, Sections 9.1, Library Char. Replace the first equation for lexLitChar with the following
      lexLitChar ('\\':s) =  map (prefix '\\') (lexEsc s)
            where
              lexEsc (c:s)     | c `elem` "abfnrtv\\\"'" = [([c],s)]
              lexEsc ('^':c:s) | c >= '@' && c <= '_'    = [(['^',c],s)]
    
    	  -- Numeric escapes
    	  lexEsc ('o':s)   	       = [prefix 'o' (span isOctDigit s)]
    	  lexEsc ('x':s)   	       = [prefix 'x' (span isHexDigit s)]
              lexEsc s@(d:_)   | isDigit d = [span isDigit s]
    
              -- Very crude approximation to \XYZ.  
              lexEsc s@(c:_)   | isUpper c = [span isCharName s]
              lexEsc _                     = []
    
              isCharName c   = isUpper c || isDigit c
    	  prefix c (t,s) = (c:t, s)
    
    (The effect is to allow octal and hexadecimal escapes in lexLitChar, just as in readLitChar.)

  • Page 48, Sections 10.3, Monads. In the definition of listFile replace "openFile" by "readFile".

  • Page 54, Sections 11, 12, 13. Replace "isIllegalOperationError" with "isIllegalOperation" throughout. Namely:
    • Section 11.1, second para after bullets (two occurrences).
    • Section 12, para 2 (two occurrences).
    • Section 13, para 2 (two occurrences).
    (It was inconsistent before.)

  • Page 54, Section 11. The signature for try should be
      try :: IO a -> IO (Either IOError a)
    

  • [May 2001] Page 57, Section 11.2.1 Semi-closed handles. Replace the sentence "Once a semi-closed handle becomes closed..." with "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."

    This change attempts to clarify the (murky) meaning of hGetContents followed by hClose.

  • [Apr 2001] Page 56-58, Section 11.2, Files and Handles. Add a section 11.2.3 to clarify the file-locking issue. It says:

    "Implementations should enforce as far as possible, at least locally to the Haskell process, multiple-reader single-writer locking on files. That is, there may either be many handles on the same file which manage input, or just one handle on the file which manages output. If any open or semi-closed handle is managing a file for output, no new handle can be allocated for that file. If any open or semi-closed handle is managing a file for input, new handles can only be allocated if they do not manage output. Whether two files are the same is implementation-dependent, but they should normally be the same if they have the same absolute path name and neither has been renamed, for example. Warning: the readFile operation (Section 7.1 of the Haskell Language Report) holds a semi-closed handle on the file until the entire contents of the file have been consumed. It follows that an attempt to write to a file (using writeFile, for example) that was earlier opened by readFile will usually result in failure with isAlreadyInUseError."

  • [Sept 2002] Page 58, Section 11.3.2 Closing Files. Replace the sentence "If the operation fails for any reason ... successfully closed." by

    "Performing hClose on a handle that has already been closed has no effect; doing so not an error. All other operations on a closed handle will fail. If hClose fails for any reason, any further operations (apart from hClose) on the handle will still fail as if "hdl" had been successfully closed."

    (The significant change here is that it is not an error to hClose a handle twice.)

  • [May 2001] Page 59, Section 11.4.2. Before "The buffer is emptied as soon as it has been written out." add: "An implementation is free to flush the buffer more frequently, but not less frequently, than specified above." (Clarification only.)

  • [May 2001] Page 59, Section 11.4.2. In the second no-buffering bullet (sixth bullet in the sub-section) add the sentence: "The hLookAhead operation implies that even a no-buffered handle may require a one-character buffer. " (Clarification only.)

  • [May 2002] Page 60, Section 11.7.1, Checking for input.
    • Split this section into two: 11.7.1 Checking for input (describing hWaitForInput and hReady), and 11.7.2 Reading input (describing hGetChar and hGetLine).

    • To the new section 11.7.2, add the following description of hGetLine exception behaviour:

      "The hGetLine fails with isEOFError if the end of file is encountered when reading the first character of the line. If hGetLine encounters end-of-file at any other point while reading in a line, it is treated as a line terminator and the (partial) line is returned."

  • Page 62, Section 11.7.2.
    • Add a new section heading "11.7.3 Reading the entire input" just before the paragraph about hGetContents.
    • Add a new section heading "11.7.4 Text output" before the paragraph about hPutChar.

  • Page 63, definition of main in Section 11.8.1. Replace the definition of "readNum" with
      where readNum :: IO Integer
    	-- Need a type signature for readLn to avoid ambiguity
    	readNum = readLn
    
    (This change merely advertises the generally useful function readLn.)

  • Page 64, Section 12, Directory functions. (More an editor's blunder than a typo.)
    • Replace the abstract definition of Permissions, and the four instances of Permissions with
        data Permissions 
          = Permissions {
              readable, writable, executable, searchable :: Bool
            }
            deriving ( Eq, Ord, Read, Show )
      
    • Remove readable, writable, executable, searchable both from the module header, and from the module body.
    • Change Permissions to Permissions(Permissions, readable, writable, executable, searchable) in the module header.

  • [Dec 2001] Page 65, Directory functions. To paragraph 4, the "Error reporting" paragraph for createDirectory, append the final clause "; or isDoesNotExistError if the new directory's parent does not exist".

  • [Nov 2001] Page 66, Directory functions. Add to the paragraph "Computation getDirectoryContents dir returns a list of all entries in dir." the following extra sentence:

    "Each entry in the returned list is named relative to the directory dir, not as an absolute path."

  • [Dec 2002] Page 70, Section 14, The Time library; and page 72, section 14.1. Add ctSec to the export list for Time (in two places).

  • [Apr 2001] Page 78, Section 16, The CPUTime library. Add cpuTimePrecision to the export list.

  • [Apr 2001] Page 81, Section 17.1, The RandomGen class. This sigificant semantic change adds a method genRange to the RandomGen class. (Extensive discussion on the Haskell mailing list made it clear that this change is essential to make the RandomGen class useful.) The following summarises the changes but not in the detailed line-by-line form used for the rest of the errata.
    • Add a method genRange :: g -> (Int,Int) to class RandomGen.
    • Give it the default method genRange g = (minBound,maxBound)
    • Add a specification of genRange
    • Change the header on page 80 to match.

  • [Apr 2001] Page 81, Section 17.1, The RandomGen class. Specify more precisely that split must deliver independent generators.

  • Page 81, Section 17.1, The RandomGen class. Bottom line on page 81: replace "show/Read instances" with "Show/Read instances" (i.e. capitalise Show).

  • Page 83, Section 17.3, The global random number generator. In the first paragraph, replace "kernal" by "kernel".

Simon Peyton Jones, simonpj@microsoft.com
haskell98-report-20080907/report/prelude-index.idx0000644000175000017500000003250011345221573021227 0ustar marcotmarcot Haskell 98 Prelude Index The Haskell 98 Report
top

Index of the Haskell 98 Prelude

Types and Synonyms

Instances which are not defined by Haskell code the Prelude (a ... is used) are not hyperlinked.

data #T() = ()  deriving (Eq, Ord, Enum, Bounded) #S6.1.5
      Instances: #IRead#() #IShow#()
data #T[a] = [] | a : [a]  deriving (Eq, Ord) #S6.1.3
      Instances: #IRead#[a] #IShow#[a] #IFunctor#[a] #IMonad#[a]
data #T(a,b) = (a,b) deriving (Eq, Ord, Bounded) #S6.1.4 
      Instances: #IRead#(a,b) #IShow#(a,b)
data a->b #S6.1.6
data #TBool = False | True deriving (Eq, Ord, Enum, Read, Show, Bounded) #S6.1.1
data #TChar #S6.1.2
       Instances: Eq Ord #IEnum#Char #IRead#Char #IShow#Char 
data #TDouble #S6.4 
       Instances: Eq Ord Enum Read Show Num Real Fractional RealFrac Floating RealFloat
data #TEither a b  e=  Left a | Right b deriving (Eq, Ord, Read, Show) #S6.1.8
type #TFilePath =  String #S7.1
data #TFloat #S6.4
       Instances: Eq Ord Enum Read Show Num Real Fractional RealFrac Floating RealFloat
data #TInt #S6.4
       Instances: Eq Ord Enum Read Show Num Real Integral Bounded
data #TInteger #S6.4
       Instances: Eq Ord Enum Read Show Num Real Integral
data #TIO a #S6.1.7
       Instances: #IFunctor#IO Monad
data #TIOError #S6.1.7
       Instances: Show Eq
data #TMaybe a  =  Nothing | Just a deriving (Eq, Ord, Read, Show) #S6.1.8
        Instances: #IFunctor#Maybe #IMonad#Maybe
data #TOrdering = LT | EQ | GT  deriving (Eq, Ord, Enum, Read, Show, Bounded) #S6.1.8
type #TReadS a = String -> [(a,String)] #S6.3.3
type #TShowS = String -> String #S6.3.3
type #TString = [Char] #S6.1.2

Constructors

#L[]#T[a]
#L:#T[a]
#L(,)#T(a,b)
#LEQ#TOrdering
#LFalse#TBool
#LGT#TOrdering
#LJust#TMaybe
#LLeft#TEither
#LLT#TOrdering
#LNothing#TMaybe
#LRight#TEither
#LTrue#TBool

Classes

class                             #TBounded a    #S6.3.7
class                             #TEnum a       #S6.3.4
class                             #TEq a         #S6.3.1
class           (Fractional a) => #TFloating a   #S6.4
class                  (Num a) => #TFractional a #S6.4
class                             #TFunctor f    #S6.3.5
class         (Real a, Enum a) => #TIntegral a   #S6.4
class                             #TMonad m      #S6.3.6
class           (Eq a, Show a) => #TNum a        #S6.4
class                   (Eq a) => #TOrd a        #S6.3.2
class                             #TRead a       #S6.3.3
class           (Num a, Ord a) => #TReal a       #S6.4
class (RealFrac a, Floating a) => #TRealFloat a  #S6.4  
class   (Real a, Fractional a) => #TRealFrac a   #S6.4
class                             #TShow a       #S6.3.3 

Functions and Methods

#table #V(!!) :: [a] -> Int -> a #&[0,1,2] !! 1 = 1 #V($) :: (a -> b) -> a -> b #&f x $ g y = f x (g y) #V($!) :: (a -> b) -> (a -> b) #&#S6.2 #V(&&) :: Bool -> Bool -> Bool #&Boolean `and' #V(||) :: Bool -> Bool -> Bool #&Boolean `or' #V(*) :: Num a => a -> a -> a #V(**) :: Floating a => a -> a -> a #V(+) :: Num a => a -> a -> a #V(++) :: [a] -> [a] -> [a] #&"abc" ++ "def" = "abcdef" #V(-) :: Num a => a -> a -> a #V(.) :: (b -> c) -> (a -> b) -> a -> c #&Function composition #V(/) :: Fractional a => a -> a -> a #V(/=) :: Eq a => a -> a -> Bool #¬ equal #V(<) :: Ord a => a -> a -> Bool #V(<=) :: Ord a => a -> a -> Bool #V(==) :: Eq a => a -> a -> Bool #V(=<<) :: Monad a => (a -> m b) -> m a -> m b #&Monadic binding #S6.3.6 #V(>) :: Ord a => a -> a -> Bool #V(>=) :: Ord a => a -> a -> Bool #V(>>) :: Monad m => m a -> m b -> m b #&Monadic binding #S6.3.6 #V(>>=) :: Monad m => m a -> (a -> m b) -> m b #&Monadic binding #S6.3.6 #V(^) :: (Num a, Integral b) => a -> b -> a #V(^^) :: (Fractional a, Integral b) => a -> b -> a #&negative exponent allowed #Vabs :: Num a => a -> a #Vacos :: Floating a => a -> a #Vacosh :: Floating a => a -> a #Vall :: (a -> Bool) -> [a] -> Bool #&all (/= 'a') "cba" = False #Vand :: [Bool] -> Bool #&and [True, True, True] = True #Vany :: (a -> Bool) -> [a] -> Bool #&any (== 'c') "abc" = True #VappendFile :: FilePath -> String -> IO () #VapplyM :: Monad m => (a -> m b) -> m a -> m b #VasTypeOf :: a -> a -> a #&Sort of a type cast #Vasin :: Floating a => a -> a #Vasinh :: Floating a => a -> a #Vatan :: Floating a => a -> a #Vatan2 :: RealFrac a => a -> a #Vatanh :: Floating a => a -> a #Vbreak :: (a -> Bool) -> [a] -> ([a], [a]) #&break (<2) [1,2,3] = ([1],[2,3]) #Vcatch :: IO a -> (IOError -> IO a) -> IO a #Vceiling :: (RealFrac a, Integral b) => a -> b #Vcompare :: Ord a => a -> a -> Ordering #Vconcat :: MonadPlus m => [m a] -> m a #&concat ["a","bc","d"] = "abcd" #VconcatMap :: (a -> [b]) -> [a] -> [b] #Vconst :: a -> b -> a #Vcos :: Floating a => a -> a #Vcosh :: Floating a => a -> a #Vcurry :: ((a, b) -> c) -> a -> b -> c #Vcycle :: [a] -> [a] #&cycle "abc" = "abcabcabc ..." #VdecodeFloat :: RealFloat a => a -> (Integer, Int) #Vdiv :: Integral a => a -> a -> a #VdivMod :: Integral a => a -> a -> (a, a) #Vdrop :: Int -> [a] -> [a] #&drop 2 "abcd" = "cd" #VdropWhile :: (a -> Bool) -> [a] -> [a] #&dropWhile (>3) [5,3,5] = [3,5] #Veither :: (a -> c) -> (b -> c) -> Either a b -> c #Velem :: Eq a => a -> [a] -> Bool #&'a' `elem` "abc" = True #VencodeFloat :: RealFloat a => Integer -> Int -> a #VenumFrom :: Enum a => a -> [a] #&[n..] #VenumFromThen :: Enum a => a -> a -> [a] #&[m,n..] #VenumFromThenTo :: Enum a => a -> a -> a -> [a] #&[m,n..o] #VenumFromTo :: Enum a => a -> a -> [a] #&[m..n] #Verror :: String -> a #& #S3.1 #Veven :: Integral a => a -> Bool #Vexp :: Floating a => a -> a #Vexponent :: RealFloat a => a -> Int #Vfail :: Monad m => String -> m a #Vfilter :: (a -> Bool) -> [a] -> [a] #Vflip :: (a -> b -> c) -> (b -> a -> c) #VfloatDigits :: RealFloat a => a -> Int #VfloatRadix :: RealFloat a => a -> Integer #VfloatRange :: RealFloat a => a -> (Int, Int) #Vfloor :: (RealFrac a, Integral b) => a -> b #Vfmap :: Functor f => (a -> b) -> f a -> f b #Vfoldl :: (a -> b -> a) -> a -> [b] -> a #&foldl (+) 0 [a,b,c] = ((0+a)+b)+c #Vfoldl1 :: (a -> a -> a) -> [a] -> a #&foldl1 (+) [a,b,c] = (a+b)+c #Vfoldr :: (a -> b -> b) -> b -> [a] -> b #&foldr (+) 0 [a,b,c] = a+(b+(c+0)) #Vfoldr1 :: (a -> a -> a) -> [a] -> a #&foldr1 (+) [a,b,c] = a+(b+c) #VfromEnum :: Enum a => a -> Int #VfromInteger :: Num a => Integer -> a #&#S3.2 #VfromIntegral :: (Integral a, Num b) => a -> b #VfromRational :: Fractional a => Rational -> a #&#S3.2 #Vfst :: (a, b) -> a #Vgcd :: (Integral a) => a -> a -> a #VgetChar :: IO Char #&eof generates an IOError #VgetContents :: IO String #VgetLine :: IO String #&eof generates an IOError #Vhead :: [a] -> a #Vid :: a -> a #Vinit :: [a] -> [a]#&init "abcd" = "abc" #Vinteract :: (String -> String) -> IO () #VioError :: IOError -> IO a #VisDenormalized :: RealFloat a => a -> Bool #VisIEEE :: RealFloat a => a -> Bool #VisInfinite :: RealFloat a => a -> Bool #VisNaN :: RealFloat a => a -> Bool #VisNegativeZero :: RealFloat a => a -> Bool #Viterate :: (a -> a) -> a -> [a] #&iterate (++ " ") "" = ["", " ", " ",...] #Vlast :: [a] -> a #&last "abcde" = "e" #Vlcm :: Integral a => a -> a -> a #Vlength :: [a] -> Int #&length "Abc" = 3 #Vlex :: ReadS String #&lex "abc def" = [("abc"," def")] #Vlines :: String -> [String] #Vlog :: Floating a => a -> a #VlogBase :: Floating a => a -> a -> a #Vlookup :: Eq a => a -> [(a, b)] -> Maybe b #Vmap :: (a -> b) -> [a] -> [b] #VmapM :: Monad m => (a -> m b) -> [a] -> m [b] #VmapM_ :: Monad m => (a -> m b) -> [a] -> m () #Vmax :: Ord a => a -> a -> a #VmaxBound :: Bounded a => a #Vmaximum :: Ord a => [a] -> a #Vmaybe :: b -> (a -> b) -> Maybe a -> b #&maybe 0 (+1) (Just 1) = 2 #Vmin :: Ord a => a -> a -> a #VminBound :: Bounded a => a #Vminimum :: Ord a => [a] -> a #Vmod :: Integral a => a -> a -> a #Vnegate :: Num a => a -> a #Vnot :: Bool -> Bool #VnotElem :: Eq a => a -> [a] -> Bool #Vnull :: [a] -> Bool #Vodd :: Integral a => a -> Bool #Vor :: [Bool] -> Bool #Votherwise :: Bool #Vpi :: Floating a => a #Vpred :: Enum a => a -> a #&pred True = False #Vprint :: Show a => a -> IO () #&adds a newline #Vproduct :: Num a => [a] -> a #VproperFraction :: (RealFrac a, Integral b) => a -> (b, a) #VputChar :: Char -> IO () #VputStr :: String -> IO () #VputStrLn :: String -> IO () #&adds a newline #Vquot :: Integral a => a -> a -> a #VquotRem :: Integral a => a -> a -> (a, a) #Vread :: Read a => String -> a #VreadFile :: FilePath -> IO String #VreadIO :: Read a => String -> IO a #&fails with IOError #VreadList :: Read a => ReadS [a] #VreadLn :: Read a => IO a #VreadParen :: Bool -> ReadS a -> ReadS a #Vreads :: Read a => ReadS a #&reads "1 2" :: [(Int,String)] = [(1," 2")] #VreadsPrec :: Read a => Int -> ReadS a #VrealToFrac :: (Real a, Fractional b) => a -> b #Vrecip :: Fractional a => a -> a #Vrem :: Integral a => a -> a -> a #Vrepeat :: a -> [a] #&repeat 'a' = "aaaaaaaaa..." #Vreplicate :: Int -> a -> [a] #&replicate 4 'a' = "aaaa" #Vreturn :: Monad m => a -> m a #Vreverse :: [a] -> [a] #&reverse "abc" = "cba" #Vround :: (RealFrac a, Integral b) => a -> b #VscaleFloat :: RealFloat a => Int -> a -> a #Vscanl :: (a -> b -> a) -> a -> [b] -> [a] #&scanl (+) 0 [1,2,3] = [0,1,3,6] #Vscanl1 :: (a -> a -> a) -> [a] -> [a] #&scanl1 (+) [1,2,3] = [1,3,6] #Vscanr :: (a -> b -> b) -> b -> [a] -> [b] #&scanr (+) 0 [1,2,3] = [6,5,3,0] #Vscanr1 :: (a -> a -> a) -> [a] -> [a] #&scanr1 (+) [1,2,3] = [6,5,3] #Vseq :: a -> b -> b #&#S6.2 #Vsequence :: Monad m => [m a] -> m [a] #Vsequence_ :: Monad m => [m a] -> m () #&do operations in sequence #Vshow :: Show a => a -> String #&#S6.3.3 #VshowChar :: Char -> ShowS #VshowList :: Show a => [a] -> ShowS #VshowParen :: Bool -> ShowS -> ShowS #VshowString :: String -> ShowS #Vshows :: Show a => a -> ShowS #&#S6.3.3 #VshowsPrec :: Show a => Int -> a -> ShowS #&#S6.3.3 #Vsignificand :: RealFloat a => a -> a #Vsignum :: Num a => a -> a #Vsin :: Floating a => a -> a #Vsinh :: Floating a => a -> a #Vsnd :: (a, b) -> b #Vspan :: (a -> Bool) -> [a] -> ([a], [a]) #&span isAlpha "ab cd" = ("ab"," cd") #VsplitAt :: Int -> [a] -> ([a], [a]) #&splitAt 2 "abcdef" = ("ab","cdef") #Vsqrt :: Floating a => a -> a #Vsubtract :: Num a => a -> a -> a #Vsucc :: Enum a => a -> a #&succ False = True #Vsum :: Num a => [a] -> a #&sum [1,2,3] = 6 #Vtail :: [a] -> [a] #&tail "abc" = "bc" #Vtake :: Int -> [a] -> [a] #&take 3 "abcde" = "abc" #VtakeWhile :: (a -> Bool) -> [a] -> [a] #&takeWhile (> 2) [3,2,1] = [3] #Vtan :: Floating a => a -> a #Vtanh :: Floating a => a -> a #VtoEnum :: Enum a => Int -> a #&toEnum 0 :: Bool = False #VtoInteger :: Integral a => a -> Integer #VtoRational :: Real a => a -> Rational #Vtruncate :: (RealFrac a, Integral b) => a -> b #Vuncurry :: (a -> b -> c) -> ((a, b) -> c) #Vundefined :: a #&#S3.1 #Vunlines :: [String] -> String #Vuntil :: (a -> Bool) -> (a -> a) -> a -> a #&until (> 3) (+ 2) 0 = 4 #Vunwords :: [String] -> String #Vunzip :: [(a, b)] -> ([a], [b]) #&unzip [('a','b'),('c','d')] = ("ac",bd") #Vunzip3 :: [(a, b, c)] -> ([a], [b], [c]) #VuserError :: String -> IOError #Vwords :: String -> [String] #&words "ab d as+3" = ["ab","d","as+3"] #VwriteFile :: FilePath -> String -> IO () #Vzip :: [a] -> [b] -> [(a, b)] #&zip "abc" "de" = [('a','d'), ('b',e')] #Vzip3 :: [a] -> [b] -> [c] -> [(a, b, c)] #VzipWith :: (a -> b -> c) -> [a] -> [b] -> [c] #&zipWith (+) [1,2] [3,4] = [4,6] #VzipWith3 :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d] #endtable
haskell98-report-20080907/report/cputime.verb0000644000175000017500000000077011345221573020306 0ustar marcotmarcot%**The Haskell 98 Library Report: CPU Time %**~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 haskell98-report-20080907/report/pragmas.verb0000644000175000017500000000430111345221573020264 0ustar marcotmarcot% % $Header: /home/cvs/root/haskell-report/report/pragmas.verb,v 1.6 2002/12/10 11:51:11 simonpj Exp $ % %**The Haskell 98 Report: Compiler Pragmas %**~header \section{Compiler Pragmas} \label{pragmas} \index{pragmas} Some compiler implementations support compiler {\em pragmas}, which are used to give additional instructions or hints to the compiler, but which do not form part of the \Haskell{} language proper and do not change a program's semantics. This chapter summarizes this existing practice. An implementation is not required to respect any pragma, but the pragma should be ignored if an implementation is not prepared to handle it. Lexically, pragmas appear as comments, except that the enclosing syntax is @{-#@ @#-}@. \subsection{Inlining} \index{inlining} @@@ decl -> @{-#@ @INLINE@ qvars @#-}@ decl -> @{-#@ @NOINLINE@ qvars @#-}@ @@@ % The optional digit represents the level of optimization at which the % inlining is to occur. If omitted, it is assumed to be 0. A compiler % may use a numeric optimization level setting in which increasing level % numbers indicate increasing amounts of optimization. Trivial % inlinings that have no % impact on compilation time or code size should have an optimization % level of 0; more complex inlinings that may lead to slow compilation % or large executables should be associated with higher optimization levels. The @INLINE@ pragma instructs the compiler to inline the specified variables at their use sites. Compilers will often automatically inline simple expressions. This may be prevented by the @NOINLINE@ pragma. \subsection{Specialization} @@@ decl -> @{-#@ @SPECIALIZE@ spec_1 @,@ ... @,@ spec_k @#-}@ & (k>=1) spec -> vars :: type @@@ Specialization is used to avoid inefficiencies involved in dispatching overloaded functions. For example, in \bprog @ factorial :: Num a => a -> a factorial 0 = 0 factorial n = n * factorial (n-1) {-# SPECIALIZE factorial :: Int -> Int, factorial :: Integer -> Integer #-} @ \eprog calls to @factorial@ in which the compiler can detect that the parameter is either @Int@ or @Integer@ will use specialized versions of @factorial@ which do not involve overloaded numeric operations. %**~footer haskell98-report-20080907/report/classes.gif0000644000175000017500000002436311345221573020110 0ustar marcotmarcotGIF87a¾@w!þSoftware: Microsoft Office,¾@ƒ     ÿÿÿÿ°ÉI«½8ëÍ»ÿ`(Ždižhª®lë¾p,Ïtmßx®ï|ïÿÀ pH,ȤrÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯° ³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇ±»Ê|̦¶ÍѵҘ֖´×Ÿ³’ÛÜ¢à‹Þá§å‡èæ¨êíë©ã~ðÊô}ïõ­ùsüú®þÜÜûn`œ€a˜PB2 a {رÏdLq‹#µ<Ïÿf ñÑÆF1?”Œ±. !ÁÈóxÒEM/7AÌÔ±g˳ôd1´EN-G7Œ²ThÊE—D}ñ´DR+W1TŘõHSžS‰t5:–$J«[„5’¶F[oÉÊ(Û„n\¦ts¬õq—e^‰•âÑWl็ᆚ$±Ö.]³u õð^¢”IH6ó²-Y7#ñŒVD0A´NÒnÞ PsØpëÕiÆ5çh€oÞ»9”;ÚömܺM"×Èã-ºÓ­…€BÛÐn0òkì蟟gŸð=|lç‚YÌCSŪýhž&gÀÿp˰q  €q Â×N_þ‘ן̱փ<ˆjVPœ‚ \~‘íGER6Ö¢…'7KwëåvOp!"¨ Ž tW( Z-6âÅ pA9øa¸tS°G‹Žp€€5’wÏ„ô0``ÜÝÇG,‘Dƒ$j‰Ëàe£NZPB!åA¥@ZfYΑ$‰àv¤@Ž@Id¦“9(ÁȤpN–Û‹*E©š?U7W¥2—¦q÷  š‡«…8K šic¡|?†xÀjlW›—÷(`â(j¦b]±EÁ¥‚ýŠn‡§5Ù´—Úÿx¤(IÔµfnSœ7 È7Ë!*€Z‡ãÜ'ÜeÃÊÄœzd¹½&‡-«Bflc·U·%ºžˆ.cF½á±uÞËV°;”Ôdùi °Àdf“Tùê›Û°î c¥tùEœ^!œ°»6ذÃ˘ÆOü_Å#§[¢¿Ç‰\¨Ê7¬nì‚”ðÖ sÎSm¯ÁAôì"F7½žÐóújÆy¡ËÙ¼4ÓFw½o™[õ[zÑ¥¸3S*Iežt]‹½Ð×g›°²Yo_ vÚq«…÷–1V÷Æ6>MÏ8VýoÖbóö÷Ûyã8¨?ªßÝzï­GbÛm7ÿÉã×[‚î´ÔxsnzkŠþ¹ê–»œôt .·ùçs:úì\y÷0^µI "$[±ãCKè§°Æpû;`àÖW¿%ISo2`ž"ˆ:ÈiÍ{p!Lû G9ø5/Æ{ÞòÖ•7 Œy3Àðè¹ÛmŠƒ"Œá;NR¯'LJvh«Þ ¹fB.®@‚SSg£F/†ÙáÜq8ßPF…ù‹ •~—¼pæk¡êr·;îÿ!±‹Ñ‹ÈÔPC¤d‡=ÄØ›°÷»Ý¹Ix ìbö´²Æ%F:öÊQF:ìÁñƒäõä¸B0°'ÛàLiÃïˆhJ¼âõ´H?.ŠñƒV´œÖ¿ÿp„ëÏ!=¹ÁäÝ€eâÇ6~–ÀRðb,b%øÅ80aS¢-?YšÂL—vD\}yÊP²-€`´å¥úFÈ%Eq—}$æ/éL ³”{|$§²©Ã[ÞŽ`skæ5…HS¦9ÔgCXLäå1…PS_ªXÈ9Ð.Ë,4½é¾ r³ï” “)OqÖ’œüÄæ?³–΃®S¡ÚtdeÂ0Ð,é3ÿ˜‡D`9•‚5KÕ³šḂl ¨±²Ut¢“™07š«Äó<÷¬åä„É>âò ‡kWNÇÓqú4‰Áÿ“_Îþ&F•&€õ|w`6÷g€œ'||Ãx ~ý €%Ç€ (u8£ ØUó`H€½áóçpÑôvë×_Æ–-æ|9µJ¢÷—á-^X6‚)ˆ?ÓÓ^^瀛çw4D¯£Aˆ8\$V.e„9xƒí%‚aDy#F å4µ>E¨‚9D‚êDS;øKõ3HBÈwoæƒò…¹÷8´ôvµc?†LXPŽiq‡ä4T…#$8?„…ñc85ØOrH8¨kN8€‡.Hž³Eu·B;õ^ZX…(D‡WH‰è³/ ƒ‡yø4ÞdE‹˜>Nw„5¸ƒN…eVÿˆ$v:³”ˆ«Ø9ŽøUm(‰|H:êF•ƒ©£J}'†®èET•>]ˆE®8Hö‰=¸‹KøIÄøEÚc‹nT"v³ˆ„ôRŒH5Ï8†9¸ŒÉdD”DP$3I$C6‹8˜ŒØÄÕø‰òÓˆÙˆŠö†¥T‹€Èˆª¸IüÇ•GôˆIÃ8Ž‚ä†ò¨o‡èt²ÄJc‚ $yh޼ø¢RÖ§Fé‡@å‡ tŽ|'div…†Ì’1åÑ?~¶=„½‚¼‹îG†M¨Rå(ÓX*É…ÆX“=G…AuˆRå’M“²hiA‰Øw[8“iˆ8Yh*Ô’‰Fh1éÿ>©‘D™2™:€Ky•UÙ1\Ù¥g•()”4i~VW£ÄZùD–©¨œ`tƒY [å?̆]¹yS Ù‹„‚J €ÖàÈ’¹—D8Uƒ†’­Âs65S8‡’ •oùpe“ZØx½™}‰—9”Ÿ™bSÉŠ 9=[T}¹¨‡•™oÓ$<4‹s‡‹HŒÙ„—‡”¨‡D”–l¸›9?r8€I•‚ C¥ùQiu‡®9—)™dâKÕM£x‰¢Œš¶_Ô”›ò“‰ñ“I·x‰ÐÙ_Iœá†ˆ?ešë¨ˆ„)œÖÖšá¹:ÁX7úØ‹ÕwŒ²“ðóF•äÿ‹õèAõ)—Ãy˜¬ù““¹yè)Næ võˆŸñœñÙ 4}XW—…ŸÿØŸ«ãl¬ƒ‰×Ù™¡9 ÛT\+¥L€øž Ê"ou’éâ ü¤Ší¸ŒÖ¹ "¤Žß8Ÿ¤ÄÎáX¤™†'kIÖŠ1ÈS„†uø@'Ç? v˜‘ E‘«¨Jn‰Ù4’¤† é›LÚJ¸¹‡Fºžè(šÈ•“…3¥¶3G•Š˜ Jpb5”Ö¡l‰$…qù¥RÚœûn"ÆbR§º‚[µ•ì)¦t¨f™_ò…Z4Ö¦z‰Jul§ˆÚmxæ¨x¨«V©œÂ^’j¦nö¨9OŸêÿœœê¥ªY€Fl[³§Ú¨eʧª± –¾ –³f‘z}”é/aZ«ê"M¹–+ b¬vB©Jc¦÷«^ú’žvª”Šs¬%IEމÊÊ]°8%jÆQÒ:§Ì ×*[2X¬kö ˜U­®¼ú–Î dèJ/êŠ/d§¨2ñú]ÈÕ®8¬öª¯ÈÈ®äZ[»z÷ú®°eP¯øP°hWþÊë ›©‹°¦±—ϺgÝ`°† ±çŠkk`'˜ »“dº  Ýꪤ:²¢Å¯ß0±j:W0+c2[ -«§Œ +Ë ;ë™òu³Ôб*{¯ä´ÊU²¡ ´úÿ”„ð³6®2Ú¬DûªÿJ¦!Q«OW ¤ÿg´Š!­Û*hÇñµÙ¶9ëh¿z²ZF õ°b ·lK©«c4Ûdh[œä¹f˜%·h™k€‹ª{[–ßꦃ‹PÄ:®ý·Ã—µ!Ь¸ª?ŠÛ~3‘¸£9ª4Á`7› Ú¸]z±kKh‹¹ç‹óà¶À2·­–fIY«º!;º­Û'«‘!»ÈcÀ°º´Ë¦ë´<û²lkº_¥»³å¸ª¹â£Ò¨Âkgf‹J+µci©ðIp2'K§&öøÆ¼„ËgCË3ñj½À‹hŒs 1·,I7 "÷mצ¼ºmÊ›¤¿KÿµK§\¢xg˜¥}+¨—:W+ÂWè š@¡=ï»ÀK‡µ>*i  b K±kXîÃÀÿû¹tkÁfVz/b¼ê²¢¨‰Á¶·z À`º¿º¾¦ |—¶FÁâ[¨§K !YÞÇ‘K·W‘ËÁsçLº¶Â5LÂè­–ŠÜ·p=2 àÄwú˜0œ®<ÄHœ€ãÉQ±·!Ð!Ä‘uH2uP…ÅxJQ‡KÁ… ¹eœÀ´P$w|û–§f<Ç«¿ºÆü´0…&¶zóavnºÅàŠÇ«Çl¼¼ŽÇ‰"ÆÐ(w*4µ©zrú|H™¾5ŒÈ‹Xð*2}½§ÿ!¶Ò¸GÇ}+’e[Åv o6Œ¾œœµˆ¥-ÛÐ-óa~2.ß—w‹™™¥øÃƒÀ5›Æ~DCFƒ[\GÊÇ?˘=òùÆëV$äÅÐ-³`¢¢(µPqg‰pîpo\pñÅR=Y²‘¤¡_8D}¤¢çèÌt {rÔ$'"dü#g"ƒ'¥*ç!b#컽øœ&SœÅ=¼ÂØ¢ZŒÑ >Wˆƒò<ϦEEBÏ&’#×ÏYu:’{­l—B+ ÍR`(¤•Ii˜¦·9›ÚäYA9Ñ,ÔmRˆm¥Ø{ý˩Ȕ;Ì -”À䉺h¢·ä‰Ý9ÅÙ©ÿE5Êý؉û*†È|\5©GÕ†ÎÇÆ–tWÝÓB½¬š[ÔÂ4ê(SÀ(Õ4IGÝŽü©ÖSmŒÆ|¥Œ{ÌAÕ¶ñÑPz¤²r y×bÍÌdM·fÝUh ¯˜£]NúŽ ÏI©•Fu¹¬$.Ç·Ë`"LJ*— #žË}âÌ‘¹¢Ëª]—ÌYr‹½KÙ©£*=ù™žp­]+ó$€ëÐûÚŒd’td$ A$¦¤y'zT:­ÔÏÍ™˜†=„6L/Â©ÄØcÝÝ9“¦qÕ}Ù¯JÓJ¬È†|›CɄЄÀÍÝsèÔÞ™›À ~ª‰ÿ4æm¨gœÆù=¯²ÈL1]˜‘³Ÿ¶}ЧÖß„ŒÞËàÇàQMŸÀHIúYB žÝä½àÓ Ì|yÛpM¹¿<€ηë}!þ’NÛþIà‰ønìÄ"^֎ł֥±åÁ¨é›)d iÑ=‚½’«sA}Ä#ΕN¹….2ÖYä–MÃ$ŠØÛ8>KÎÐÊ™ú­É|äå x™Wß[ †¬<êåÒBŒ–à†¬à÷ ›^¤Ozß0´‡uG!ûMÀ=ºÞ'úšü›º™‹ËyÞE>ÒäívTàÕžõ¶HýàÏ܆Ëè}X£Â'¡˜˜è æ™þå…¡ì¼–8ÿájéGø•%ŽóœðyèH ÙÔ)E‚®Ð‰=ŸJ¸Ûîø^ê­èšŽê˜ ‚¹¾Ô^Až£±~áÞŠ€Në:ºŸU8ÛSŽØ.¥d6þeCþâYüë”~Ö)>éºnáÞ}샪ã ÉÃVz‘=~‘¹¤<æ^šÖÔm˜Â–©¤i9î¤ÊEªÂXžäÄlì\ŽÛÿÎÇé Qf¾DÞ–az)UÇ Ot´ðüÞÛæ¹êuî®ùç¿ià¨\”kž¿ßÎéü^·/óåq¡Þê—žEåDÎìDòw,Ä %ìkì(ó7ƪ®ëäßâ1ÿÀÅ¢6Ïí®^ô­ìʤ6Â=ïÿóŽEím<ÁцDÎÎê'Šól´L Œ¿J/ëo=$¬ª¸<|–ö¾´3ö:®ñ"ÁyÎóOG¯ðôËõ1L©ŠêñÅ~Ý•Îã®´ëõ›¹ ¬¦®Âeé°„é܆ç£fcÁJi‡鯣øDÿŸ´f·:•õj9ãÛöòåi4–¯øž<´ÐµÊ]{«m‰úÖÍ´«@UùqÍÁ’e c¤ú´ßô„ïPªï¡Ï¹%‘œÏîK¿ûœö1¥.±#ª^ë·¦üÂüïSºß©"VüÎ óÖäØêú˜¶¨>Á ·Où1 þˆk¾W;ƒýÚžñ…÷ÏNÑë3Þ>ÿþ;'1ðO¸g‹¼åKèªvÚ¤Õ^œõæ½I/A±49 UUouO8–­uþl<7YœÔÿp$$¢\G_Q9ãå’Kh«éŒV5O+ÖºÔn½—©®û妊c2­\§mm7ÛÌŽCkÜz.Üçwþ¬9;ÀŸ0<Â3·>ÄŽEÆFÃÃÇ“HÉI1ÅËGMŠJ;NÂ;²ÐN°LS™ÒÇO½ÔŒV××7ÔÙ?[XÁºÕ¯Ñ<ÞY`aMâ^]?c9e*ÜæhD鳨ZVëkç[ÒmîbäIêçpqïaíóq¦òKöwsõo/ødÆìü]ýiúú-÷~ê·/MAVÿJ<¥°‘"„ ÿF”è°E:‹4ŽÉsvb±Œ†\§‡ã9j¾,2…‘ä„q_1“9ó% —7ižtH¬¦-–s¾¦ò¦§v<3:ò(˜RFŸÂ$ÇtÕ©¬ÞÈZ¡àO”/ )%J–äÖ­³ý'Õ«Ù£b»"u:×W¶=ç<É«Pî\®ÝÄ¢ïJ3†ë…»r¨NG#¼øìd¯!KÆl„sçuiÖ ‰ä…iËPï]-Ú^ëÈ­ãjžùy‡moHœàÆ¥[Ì‘ž´ß¥¦ACãÕoZÞ’t°æ»]G‹ÎÔ_÷‹CTŸN}‚ôËE­mü£Ž±y«(·×è1ð Ñ1HAQ"„D¿äxêAZ.˜2J£É.íÐòç25fÛm²éL„/.e,T%ˆÎ\sñª¬|êj‰ãÆs €€ü)Ê$z¦*a† -ŰÑ<ÞØ °¡ßZ!€~cÏ7•ÌÌïV„0Ì^¢äãÌx®Ä’­@8€¼´23KzÏ;ßHË* Ódó;€(À*( €C@ HaÎÄTÀt€&HàPD)ÝO+ ñ+s‚G#´‚OSH@Ô·bÍl…M;m ÕP)P  @ Î7ÑÿÛ“®>Q…”N.YõÕ]¡Q-IÐôÐD+°´ÐX˜ Ôža¿[ •µX(S4m`h)@L –²8'˜ØrÏMwÝ îÍwÔSùºtÞz'0Øaè²wIÕÓ¬ôw€ÐýuXíÅ·XSø6ÜjÛ}w-A)ä¶[Š ‡`ˆµÓ·lá}qsá hN€†IŽùËp€ÞÙ]tý¶gúå-˜Ó¢F•§¥êJCzÇ ).«D=jDéÕ=ªtƒXݨû’ÚÓ³zt¢i([åú¦·r5®h¥hPM‰GóŒÇžiKç`có¥rÞqº[a gØj)ZÜ ¥+éXÄ6A“„BgsÂ|¦²ŸCýêe¹xL¦zµ£ai X‘âCŠYBíi¥)™ ¬ù‘-l Ÿ¨°CŽ’ÿ’]œãÛjž¨Ã«nË¢ÜѾ(7Ôì<’ÄÛ E×MÐáOGXr]RÌÇÓˆx"#óV²@éík‡ó^òÞ‡½«MHžég¾ÙÁ¯z€’Üí*=rËqÊ‹„vÀE.‚—Ñ`óÁÁ„b.+K[›grÂò©‰ S%ê€D÷­.l4ÈHŸx0)F¡N ÉUx#u/ŒaáîÈxM$¶±#oŒcû"·Ç²}Šdí¹ÇG懎ÿ[%GÙheqò…w,e,³AY¶°k¹ìG&«!Ìzñ—Iä 1gˆÇfv$s7¼¡2³ùÌ×I3Š„,g×™±x6­_ÿùåöèÎkþ3‘Eóf>ƹЀ2¢i¬èE3Úº‚f$¤#=g WYÍw¾ô ”áN÷yŽ¡æ2x-å“Õ‡Ýש³œj½¨:Ó¤Œ§¬Ëip ÐĶÎNc]-gXÇÔ–üõŠÅ"b^«öÉñ /¥7³šdC ×)Q±Ã2·’@;ÚVM²Zôëlò$ÇÃÛ¶¬ŸÃÛ{ضöq® šu{[Ó#ž¶„clïÎ[5–¦ïRô=&4ÿ;»î…òY^k¿¼·Ý¶÷Žî #U·ÛšÆE3¦#-ñvÔ¨Âà^î¥1®ÖAÒ[ã‹þ8·ó]JÕLšˆlqRsKÍï.Ÿ·ZàÕ¤'þÿŽ YºÅö”)ñH>—ܶªÝÐ<¢#˜ê_v*R+ÌWü©Ã šä@€CIMlZâR–«`5D¤'Hk$Àúªh¾¬™Žžf+;ën…ö 1ªÜJ:!oC€*2À](WÇÒÅ1Q™ \\·ÀÃTæ¼¾¬çm阹<&4‘e­S‡\ß=ø‚ÌçÍD5Ì‘‚pÍ)\¨í4;üìŽC— ¼ânú¢³ZDé#ß9-/sÉž/„¨WE{Ê õ \>W?ðýÄíl£(~àøú8Z7?÷œ§;¿ch™Ahµƒ> nWØÊ]™µ;ûÜë3ðý’¡AÛ¯zпyÝÿߨú·ÝüОˆIï)ŸýÃç“¿›üCÀðñý1Ѫ>B:Q " h; û)p¹ š—K9Œ¡!£ã»Š ,!tj±å3œ€J ð¡¥ò´ùòd3…“6†39\¸—Âz»ÁR,¸s\)Cä…iB‰±,Í ¥Ùk¬ÉjAN´Ã “:¨ÃÀc3E}ä.Š<73I’D¢ŒK¸QkP«»™|. YÃI•l‹ ḟ3G˜ÜÅÿðH8¢$§“‹6Ÿd:ï‚7¡Ä,rkÊÞC¯¨| g‹·›,Ê¡ô/ºÓÊß°6xãJ&a0`#¢7r‹F@Ê5ËRc±ž[Ë•47·Œ´¤K½lI¾Ì1¹D¶½ Ì%DGLÃtCÂdÃ\LyLÌaLÈ$ËøÛ´È¬ÌR¬H;³LÍÄ̾tŒÍüL\ÄàMÒ¼µÊÒLÍ&œFSM׬˚\Š×œM ŒÃþ MܬÀˤÌÜìM¥êÌÑôMáŒÈØôÌáôMª¼ŽãÎä4…¤\ÎÌMÞ„Î×lÎc¤NڴΤÃÎÙÔÎnäÎê”ÌXÏÔôN±#ÏÒ4ÏAOÒTOäcÏÿÍtOÄ„OÍ”O1¤ÏøOýÄÏ}dÍÞàOдO+ÐÈP.$PÆ4ÐÆDÐÅTPaÐÝOÿ„PRsÐñ¤PôP ÅPùãG‘ãPÁÔPÑBQ¬Ke´ å° L=ÑÝ˵ɥˈÕË].¸dÊç 9é¼Ë¼"#R"EÎJËPKOcÒ´ìÑ MR “·<+2(µQ)…@ûÑ«¶«RÇ<Ê\“´oãÒëY¿ü»Ø#Îâ4í~­–환ŠËû;qV†‘C`‹×Y%ŒÐ@3°=ˆ9˜á‹ÕóŸ_%Ô;¼Ó™“LØ.]Øj¦¡ äDÅšï`YŒÅÕÄßû¦?¾âKÿ Ü9”­VWwmYÎd˜XV‹IRrFmË ­ÍSÉ> `?­íô+Yø£µp@êáV< Í~Ô›ƒÕ©€ö™™¢ã>YÅÚTÕX ê$ûK—LÙì¿•Yž (,Ÿšö™ÌÕêS XÂ]Ûô‘˜ `ý+`É[úñ»¹¥ÛŒ}P@¤0Ç‚AfÝ9šƒœ° Ý4]wAØIaËÅ=/CP×ÕÄÐu˜½ƒ!G©ÁPÁÝ.ÉKÎåY»}×½U0ý³Ü2M TÞJë´æÕUiDU8’ÞÃçµÞD{ÉÝØäå^N%¹ì_"CÓñ-ÑòU¶ðßÿè%ßûÔÞCC-UCÁYƒÑ–=¤ßŸÁ‚5ä‰üÅÞø•_±¢Ã‚„ž„t^è-H€Úø;[ä5Þï5_–â¼þƪú\÷}ÅÚº`|Œ)ÝtÔ‰T4Jl*Uì`zDÜ X¶ZŸAE²"•mÌÄÜ\XácEØ_´à`ÔFwtÅedZàÜá˜ó`ˆ4©„GÅ‚×K%`BäákF,ªÜǦµæU|GpÌ+­¬ÚÁ\_öÅbkDa–+.~H+vÙ¸‚b3æb/nE·©ÐïtJu4àG9Þcf½‘Âã(nE4ä þM<Ó/´0þÖ‚šâzÒ,ÉÒÅÍý­3ìÀ¦;«ÿaHKœŽôÅ$<Óٕ׋üÉ^P“eyãCVÔ0æÆ”Lå>^iºŒô“ždå†[®¯H…e&Æå\6¸õ‚8vûÐJ•ÓêÚI^CH“ÈSgNæLýÏfž®?UÓms3¬„sDQ¼æÂÌfqÔ°<+­ÛǤÒ&c„q–ÍÛd0(ç ÄÀ,fÔ¬yÝv®r&Þ( ÎpþËzNBÞçsçÅЃSç„^Þ{nhUB††h‡+TŠFϤœè‹ŽN‹Þèå4Sƒöè#th‘vMuÖè’þ¯GKéðÜB–nO”–ä—–Q2œiÈ iµéÃŒénÖé©äiOöéŠê;ê %jÆ5ê‹Cê´Tê cê§sꯄêÛ¢jŸæfÁj©†ÑúÌç­vN­žê‚k².k³>k´Nkµ^k¶6ë¯~k¸Žk¹žkº®k»¾k¼Îk½Þk¾îk¿þkÀlÁlÂ.lÃ>lÄNlÅ^lÆnlÇ~lÈŽlÉžlÊ®l˾lÌÎlÍÞl/ˆ;haskell98-report-20080907/report/preface-jfp.verb0000644000175000017500000002672211345221573021027 0ustar marcotmarcot %**Preface %*section %**~sheader \markboth{PREFACE}{PREFACE} \begin{center} {\Large \bf Preface} \end{center} \vspace{.2in} \begin{quote} ``{\em Some half dozen persons have written technically on combinatory logic, and most of these, including ourselves, have published something erroneous. Since some of our fellow sinners are among the most careful and competent logicians on the contemporary scene, we regard this as evidence that the subject is refractory. Thus fullness of exposition is necessary for accuracy; and excessive condensation would be false economy here, even more than it is ordinarily.}'' \begin{flushright} Haskell B.~Curry and Robert Feys \\ in the Preface to {\em Combinatory Logic} \cite{curry&feys:book}, May 31, 1956 \end{flushright} \end{quote} \vspace{.2in} \noindent In September of 1987 a meeting was held at the conference on Functional Programming Languages and Computer Architecture (FPCA~'87) in Portland, Oregon, to discuss an unfortunate situation in the functional programming community: there had come into being more than a dozen non-strict, purely functional programming languages, all similar in expressive power and semantic underpinnings. There was a strong consensus at this meeting that more widespread use of this class of functional languages\index{functional language} was being hampered by the lack of a common language. It was decided that a committee should be formed to design such a language, providing faster communication of new ideas, a stable foundation for real applications development, and a vehicle through which others would be encouraged to use functional languages. This document describes the result of that committee's efforts: a purely functional programming language called \Haskell{}, \index{Haskell@@\Haskell{}} named after the logician Haskell B.~Curry\index{Curry, Haskell B.} whose work provides the logical basis for much of ours. \section*{Goals} The committee's primary goal was to design a language that satisfied these constraints: \begin{enumerate} \item It should be suitable for teaching, research, and applications, including building large systems. \item It should be completely described via the publication of a formal syntax and semantics. \item It should be freely available. Anyone should be permitted to implement the language and distribute it to whomever they please. \item It should be based on ideas that enjoy a wide consensus. \item It should reduce unnecessary diversity in functional programming languages. \end{enumerate} \section*{\Haskell{} 98: language and libraries} The committee intended that \Haskell{} would serve as a basis for future research in language design, and hoped that extensions or variants of the language would appear, incorporating experimental features. \Haskell{} has indeed evolved continuously since its original publication. By the middle of 1997, there had been four iterations of the language design (the latest at that point being \Haskell{} 1.4). At the 1997 \Haskell{} Workshop in Amsterdam, it was decided that a stable variant of \Haskell{} was needed; this stable language is the subject of this Report, and is called ``\Haskell{} 98''. \Haskell{} 98 was conceived as a relatively minor tidy-up of \Haskell{} 1.4, making some simplifications, and removing some pitfalls for the unwary. It is intended to be a ``stable'' language in sense the {\em implementors are committed to supporting \Haskell{} 98 exactly as specified, for the foreseeable future}. The original \Haskell{} Report covered only the language, together with a standard library called the @Prelude@. By the time \Haskell{} 98 was stabilised, it had become clear that many programs need access to a larger set of library functions (notably concerning input/output and simple interaction with the operating system). If these program were to be portable, a set of libraries would have to be standardised too. A separate effort was therefore begun by a distinct (but overlapping) committee to fix the \Haskell{} 98 Libraries. The \Haskell{} 98 Language and Library Reports were published in February 1999. \section*{Revising the \Haskell{} 98 Reports} After a year or two, many typographical errors and infelicities had been spotted. I took on the role of gathering and acting on these corrections, with the following goals: \begin{itemize} \item Correct typographical errors. \item Clarify obscure passages. \item Resolve ambiguities. \item With reluctance, make small changes to make the overall language more consistent. \end{itemize} This task turned out to be much, much larger than I had anticipated. As \Haskell{} becomes more widely used, the Report has been scrutinised by more and more people, and I have adopted hundreds of (mostly small) changes as a result of their feedback. The original committees ceased to exist when the original \Haskell{} 98 Reports were published, so every change was instead proposed to the entire \Haskell{} mailing list. This document is the outcome of this process of refinement. It includes both the \Haskell{} 98 Language Report and the Libraries Report, and constitutes the official specification of both. It is {\em not} a tutorial on programming in \Haskell{} such as the `Gentle Introduction' \cite{tutorial}, and some familiarity with functional languages is assumed. The entire text of both Reports is available online (see ``\Haskell{} resources'' below). \section*{Extensions to \Haskell{} 98} \Haskell{} continues to evolve, going well beyond \Haskell{} 98. For example, at the time of writing there are \Haskell{} implementations that support: \begin{description} \item[Syntactic sugar,] including: \begin{itemize} \item pattern guards; \item recursive do-notation; \item lexically scoped type variables; \item meta-programming facilities; \end{itemize} \item[Type system innovations,] including: \begin{itemize} \item multi-parameter type classes; \item functional dependencies; \item existential types; \item local universal polymorphism and arbitrary rank-types; \end{itemize} \item[Control extensions,] including: \begin{itemize} \item monadic state; \item exceptions; \item concurrency; \end{itemize} \end{description} There is more besides. \Haskell{} 98 does not impede these developments. Instead, it provides a stable point of reference, so that those who wish to write text books, or use \Haskell{} for teaching, can do so in the knowledge that \Haskell{} 98 will continue to exist. \section*{\Haskell{} Resources} \label{sect:resources} The \Haskell{} web site \bprog @ http://haskell.org @ \eprog gives access to many useful resources, including: \begin{itemize} \item Online versions of the language and library definitions, including a complete list of all the differences between \Haskell{} 98 as published in February 1999 and this revised version. \item Tutorial material on \Haskell{}. \item Details of the \Haskell{} mailing list. \item Implementations of \Haskell{}. \item Contributed \Haskell{} tools and libraries. \item Applications of \Haskell{}. \end{itemize} You are welcome to comment on, suggest improvements to, and criticise the language or its presentation in the report, via the \Haskell{} mailing list. \section*{Building the language} \Haskell{} was created, and continues to be sustained, by an active community of researchers and application programmers. Those who served on the Language and Library committees, in particular, devoted a huge amount of time and energy to the language. Here they are, with their affiliation(s) for the relevant period: \begin{center} Arvind (MIT) \\ Lennart Augustsson (Chalmers University) \\ Dave Barton (Mitre Corp) \\ Brian Boutel (Victoria University of Wellington) \\ Warren Burton (Simon Fraser University) \\ Jon Fairbairn (University of Cambridge) \\ Joseph Fasel (Los Alamos National Laboratory) \\ Andy Gordon (University of Cambridge) \\ Maria Guzman (Yale University) \\ Kevin Hammond [editor] (University of Glasgow) \\ Ralf Hinze (University of Bonn) \\ Paul Hudak [editor] (Yale University) \\ John Hughes [editor] (University of Glasgow; Chalmers University) \\ Thomas Johnsson (Chalmers University) \\ Mark Jones (Yale University, University of Nottingham, Oregon Graduate Institute) \\ Dick Kieburtz (Oregon Graduate Institute) \\ John Launchbury (University of Glasgow; Oregon Graduate Institute) \\ Erik Meijer (Utrecht University) \\ Rishiyur Nikhil (MIT) \\ John Peterson [editor] (Yale University) \\ Simon Peyton Jones [editor] (University of Glasgow; Microsoft Research Ltd) \\ Mike Reeve (Imperial College) \\ Alastair Reid (University of Glasgow) \\ Colin Runciman (University of York) \\ Philip Wadler [editor] (University of Glasgow) \\ David Wise (Indiana University) \\ Jonathan Young (Yale University) \end{center} Those marked [editor] served as the co-ordinating editor for one or more revisions of the language. In addition, dozens of other people made helpful contributions, some small but many substantial. They are as follows: Kris Aerts, Hans Aberg, Sten Anderson, Richard Bird, Stephen Blott, Tom Blenko, Duke Briscoe, Paul Callaghan, Magnus Carlsson, Mark Carroll, Manuel Chakravarty, Franklin Chen, Olaf Chitil, Chris Clack, Guy Cousineau, Tony Davie, Craig Dickson, Chris Dornan, Laura Dutton, Chris Fasel, Pat Fasel, Sigbjorn Finne, Michael Fryers, Andy Gill, Mike Gunter, Cordy Hall, Mark Hall, Thomas Hallgren, Matt Harden, Klemens Hemm, Fergus Henderson, Dean Herington, Ralf Hinze, Bob Hiromoto, Nic Holt, Ian Holyer, Randy Hudson, Alexander Jacobson, Patrik Jansson, Robert Jeschofnik, Orjan Johansen, Simon B.~Jones, Stef Joosten, Mike Joy, Stefan Kahrs, Antti-Juhani Kaijanaho, Jerzy Karczmarczuk, Wolfram Kahl, Kent Karlsson, Richard Kelsey, Siau-Cheng Khoo, Amir Kishon, Feliks Kluzniak, Jan Kort, Marcin Kowalczyk, Jose Labra, Jeff Lewis, Mark Lillibridge, % The doubled "" is turned into one by the verbatim preprocessor % Bj\""{o}rn Lisper, Bjorn Lisper, Sandra Loosemore, Pablo Lopez, Olaf Lubeck, Ian Lynagh, Christian Maeder, Ketil Malde, Simon Marlow, Michael Marte, Jim Mattson, John Meacham, Sergey Mechveliani, Gary Memovich, Randy Michelsen, Rick Mohr, Andy Moran, Graeme Moss, Henrik Nilsson, Arthur Norman, Nick North, Chris Okasaki, Bjarte M. {\O}stvold, Paul Otto, Sven Panne, Dave Parrott, Ross Paterson, Larne Pekowsky, Rinus Plasmeijer, Ian Poole, Stephen Price, John Robson, Andreas Rossberg, George Russell, Patrick Sansom, Michael Schneider, Felix Schroeter, Julian Seward, Nimish Shah, Christian Sievers, Libor Skarvada, Jan Skibinski, Lauren Smith, Raman Sundaresh, Josef Svenningsson, Ken Takusagawa, Satish Thatte, Simon Thompson, Tom Thomson, Tommy Thorn, Dylan Thurston, Mike Thyer, Mark Tullsen, David Tweed, Pradeep Varma, Malcolm Wallace, Keith Wansbrough, Tony Warnock, Michael Webber, Carl Witty, Stuart Wray, and Bonnie Yantis. Finally, aside from the important foundational work laid by Church, Rosser, Curry, and others on the lambda calculus, it is right to acknowledge the influence of many noteworthy programming languages developed over the years. Although it is difficult to pinpoint the origin of many ideas, the following languages were particularly influential: Lisp (and its modern-day incarnations Common Lisp and Scheme); Landin's ISWIM; APL; Backus's FP \cite{back78}; ML and Standard ML; Hope and Hope$^{+}$; Clean; Id; Gofer; Sisal; and Turner's series of languages culminating in Miranda\footnote{{\rm Miranda} is a trademark of Research Software Ltd.}. Without these forerunners \Haskell{} would not have been possible. \vspace{1in} Simon Peyton Jones \\ Cambridge, September 2002 %**~sfooter haskell98-report-20080907/report/locale.verb0000644000175000017500000000065311345221573020077 0ustar marcotmarcot%**The Haskell 98 Library Report: Locale %**~header \section{Locale} \label{locale} \index{locale} \outline { \inputHS{lib-hdrs/Locale} } The @Locale@ library provides the ability to adapt to local conventions. At present, it supports only time and date information as used by @calendarTimeToString@ from the @Time@ library. \clearpage \subsection{Library {\tt Locale}} \inputHS{lib-code/Locale} %**~footer haskell98-report-20080907/report/html.config0000644000175000017500000000274011345221573020112 0ustar marcotmarcotaux=haskell.aux htmldir=haskell98-report-html/ refs=reportrefs files= preface-jfp.verb files= intro.verb files= lexemes.verb files= exps.verb files= decls.verb files= modules.verb files= basic.verb files= io-13.verb files=standard-prelude.verb files=syntax-iso.verb files=literate.verb files=derived.verb files=pragmas.verb files=ratio.verb files=complex.verb files=numeric.verb files=ix.verb files=array.verb files=list.verb files=maybe.verb files=char.verb files=monad.verb files=io.verb files=directory.verb files=system.verb files=time.verb files=locale.verb files=cputime.verb files=random.verb files=haskell.bbl index=haskell98-report-html/index98.html style=article ~top=top ~style= ~id=The Haskell 98 Report
~back=back ~nxt=next ~funct=function index ~contents=contents ~foot=
December 2002 ~footer=
~id~top | ~back | ~nxt | ~contents | ~funct ~foot ~sfooter=
~id~top | back | ~nxt | ~contents | ~funct ~foot ~efooter=
~id~top | ~back | next | ~contents | ~funct ~foot ~header=~style ~id ~top | ~back | ~nxt | ~contents | ~funct

~sheader=~style ~id ~top | back | ~nxt | ~contents | ~funct

~eheader=~style ~id ~top | ~back | next | ~contents | ~funct

~indexHeader=Haskell 98 Contents~style ~id~top | ~funct

Haskell 98 Report: Contentsx

haskell98-report-20080907/report/lambda.gif0000644000175000017500000000175011345221573017666 0ustar marcotmarcotGIF87aDD÷3f™Ìÿ3333f3™3Ì3ÿff3fff™fÌfÿ™™3™f™™™Ì™ÿÌÌ3ÌfÌ™ÌÌÌÿÿÿ3ÿfÿ™ÿÌÿÿ3333f3™3Ì3ÿ3333333f33™33Ì33ÿ3f3f33ff3f™3fÌ3fÿ3™3™33™f3™™3™Ì3™ÿ3Ì3Ì33Ìf3Ì™3ÌÌ3Ìÿ3ÿ3ÿ33ÿf3ÿ™3ÿÌ3ÿÿff3fff™fÌfÿf3f33f3ff3™f3Ìf3ÿffff3fffff™ffÌffÿf™f™3f™ff™™f™Ìf™ÿfÌfÌ3fÌffÌ™fÌÌfÌÿfÿfÿ3fÿffÿ™fÿÌfÿÿ™™3™f™™™Ì™ÿ™3™33™3f™3™™3Ì™3ÿ™f™f3™ff™f™™fÌ™fÿ™™™™3™™f™™™™™Ì™™ÿ™Ì™Ì3™Ìf™Ì™™ÌÌ™Ìÿ™ÿ™ÿ3™ÿf™ÿ™™ÿÌ™ÿÿÌÌ3ÌfÌ™ÌÌÌÿÌ3Ì33Ì3fÌ3™Ì3ÌÌ3ÿÌfÌf3ÌffÌf™ÌfÌÌfÿ̙̙3Ì™fÌ™™Ì™ÌÌ™ÿÌÌÌÌ3ÌÌfÌÌ™ÌÌÌÌÌÿÌÿÌÿ3ÌÿfÌÿ™ÌÿÌÌÿÿÿÿ3ÿfÿ™ÿÌÿÿÿ3ÿ33ÿ3fÿ3™ÿ3Ìÿ3ÿÿfÿf3ÿffÿf™ÿfÌÿfÿÿ™ÿ™3ÿ™fÿ™™ÿ™Ìÿ™ÿÿÌÿÌ3ÿÌfÿÌ™ÿÌÌÿÌÿÿÿÿÿ3ÿÿfÿÿ™ÿÿÌÿÿÿ (((555CCCPPP]]]kkkxxx†††“““¡¡¡®®®»»»ÉÉÉÖÖÖäääñññÿÿÿ,DDͯ H° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ£Ç CŠI²¤I¬NnL©2#Ë–_¬(s&Åš×pÚL¨S`ÏþêSáP C5ºt¢Ò¦ŸB-(ujQ««NÕºkC®PÁ.;Ö+C²Dk¢=‰s­É¶fƒtK²'ÝBãæä7iß…w;* Ìq0Ö§„5">œµkc¦oM ù1BÊ•-GÑ.[‰˜;ßD:ÚæÚМõª^ͺµë×°cËž=1`;haskell98-report-20080907/report/time.verb0000644000175000017500000000535611345221573017603 0ustar marcotmarcot%**The Haskell 98 Library Report: Dates and Times %**~header \section{Dates and Times} \label{time} \index{time} \index{time of day}\index{clock time} %% Note: HBC has Leap year calculations too. %% My feeling is that these are unnecessary given the much stronger %% ability here to find the differences between dates. \outline { \inputHS{lib-hdrs/Time} } \outline{ \inputHS{lib-hdrs/Time1} } The @Time@ library provides standard functionality for clock times, including timezone information. It follows RFC~1129 in its use of Coordinated Universal Time (UTC). @ClockTime@ is an abstract type, used for the system's internal clock time. Clock times may be compared directly or converted to a calendar time @CalendarTime@ for I/O or other manipulations. @CalendarTime@ is a user-readable and manipulable representation of the internal @ClockTime@ type. The numeric fields have the following ranges. \outline{ \begin{tabbing} \ignorehtml{ \ \ \ \=ctpicosec\ \ \ \ \=-maxInt\ \=\ldots\ \=$(10^{12})-1$\ \ \ \ \ \=\kill} \>\underline{Value}\>\>\underline{Range}\>\>\underline{Comments} \\ \\ \>ctYear\>\>-maxInt\'$\ldots$\>maxInt\>Pre-Gregorian dates are inaccurate \\ \>ctDay\>\>1\'$\ldots$\>31 \\ \>ctHour\>\>0\'$\ldots$\>23\\ \>ctMin\>\>0\'$\ldots$\>59\\ \>ctSec\>\>0\'$\ldots$\>61\>Allows for two Leap Seconds\\ \>ctPicosec\>\>0\'$\ldots$\>$(10^{12})-1$ \\ \>ctYDay\>\>0\'$\ldots$\>365\>364 in non-Leap years \\ \>ctTZ\>\>-89999\'$\ldots$\>89999\>Variation from UTC in seconds \end{tabbing} } The "ctTZName" field is the name of the time zone. The "ctIsDST" field is @True@ if Daylight Savings Time would be in effect, and @False@ otherwise. The @TimeDiff@ type records the difference between two clock times in a user-readable way. Function @getClockTime@ returns the current time in its internal representation. The expression @addToClockTime@~"d"~"t" adds a time difference "d" and a clock time "t" to yield a new clock time. The difference "d" may be either positive or negative. The expression @diffClockTimes@~"t1"~"t2" returns the difference between two clock times "t1" and "t2" as a @TimeDiff@. Function @toCalendarTime@~"t" converts "t" to a local time, modified by the timezone and daylight savings time settings in force at the time of conversion. Because of this dependence on the local environment, @toCalendarTime@ is in the @IO@ monad. Function @toUTCTime@~"t" converts "t" into a @CalendarTime@ in standard UTC format. @toClockTime@~"l" converts "l" into the corresponding internal @ClockTime@ ignoring the contents of the "ctWDay", "ctYDay", "ctTZName", and "ctIsDST" fields. Function @calendarTimeToString@ formats calendar times using local conventions and a formatting string. \subsection{Library {\tt Time}} \inputHS{lib-code/Time} %**~header haskell98-report-20080907/report/io.verb0000644000175000017500000005627111345221573017256 0ustar marcotmarcot%**The Haskell 98 Library Report: Input/Output %**~header \section{Input/Output} \label{IO} \index{input/output} \index{I/O} \indextt{IO} % Gotta break the figure ... \outline{ \inputHS{lib-hdrs/IO} } \outline{ \inputHS{lib-hdrs/IO1} } The monadic I/O system used in \Haskell{} is described by the \Haskell{} language report. Commonly used I/O functions such as @print@ are part of the standard prelude and need not be explicitly imported. This library contain more advanced I/O features. Some related operations on file systems are contained in the @Directory@ library. \subsection{I/O Errors} \index{I/O errors} \label{IOError} Errors of type @IOError@ are used by the I/O monad. This is an abstract type; the library provides functions to interrogate and construct values in @IOError@:\indextycon{IOError} \begin{itemize} \item @isAlreadyExistsError@\indextt{isAlreadyExistsError} -- the operation failed because one of its arguments already exists. \item @isDoesNotExistError@\indextt{isDoesNotExistError} -- the operation failed because one of its arguments does not exist. \item @isAlreadyInUseError@\indextt{isAlreadyInUseError} -- the operation failed because one of its arguments is a single-use resource, which is already being used (for example, opening the same file twice for writing might give this error). \item @isFullError@\indextt{isFullError} -- the operation failed because the device is full. \item @isEOFError@\indextt{isEOFError} -- the operation failed because the end of file has been reached. \item @isIllegalOperation@\indextt{isIllegalOperation} -- the operation is not possible. \item @isPermissionError@\indextt{isPermissionError} -- the operation failed because the user does not have sufficient operating system privilege to perform that operation. \item @isUserError@\indextt{isUserError} -- a programmer-defined error value has been raised using @fail@.\indextt{fail} \end{itemize} All these functions return a @Bool@, which is @True@ if its argument is the corresponding kind of error, and @False@ otherwise. Any computation which returns an @IO@ result may fail with @isIllegalOperation@. Additional errors which could be raised by an implementation are listed after the corresponding operation. In some cases, an implementation will not be able to distinguish between the possible error causes. In this case it should return @isIllegalOperation@. Three additional functions are provided to obtain information about an error value. These are @ioeGetHandle@\indextt{ioeGetHandle} which returns @Just@~"hdl" if the error value refers to handle "hdl" and @Nothing@ otherwise; @ioeGetFileName@\indextt{ioeGetFileName} which returns @Just@~"name" if the error value refers to file "name", and @Nothing@ otherwise; and @ioeGetErrorString@\indextt{ioeGetErrorString} which returns a string. For ``user'' errors (those which are raised using @fail@), the string returned by @ioeGetErrorString@ is the argument that was passed to @fail@; for all other errors, the string is implementation-dependent. The @try@ function returns an error in a computation explicitly using the @Either@ type. The @bracket@ function captures a common allocate, compute, deallocate idiom in which the deallocation step must occur even in the case of an error during 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. \subsection{Files and Handles} \Haskell{} interfaces to the external world through an abstract {\em file system}\index{file system}. This file system is a collection of named {\em file system objects}, which may be organised in {\em directories}\index{directories} (see @Directory@). In some implementations, directories may themselves be file system objects and could be entries in other directories. For simplicity, any non-directory file system object is termed a {\em file}\index{file}, although it could in fact be a communication channel, or any other object recognised by the operating system. {\em Physical files}\index{physical file} are persistent, ordered files, and normally reside on disk. File and directory names are values of type @String@, whose precise meaning is operating system dependent. Files can be opened, yielding a handle which can then be used to operate on the contents of that file. \label{Handles} \index{handles} \Haskell{} defines operations to read and write characters from and to files, represented by values of type @Handle@. Each value of this type is a {\em handle}: a record used by the \Haskell{} run-time system to {\em manage} I/O with file system objects. A handle has at least the following properties: \begin{itemize} \item whether it manages input or output or both; \item whether it is {\em open}, {\em closed} or {\em semi-closed}; \item whether the object is seekable; \item whether buffering is disabled, or enabled on a line or block basis; \item a buffer (whose length may be zero). \end{itemize} Most handles will also have a current I/O position indicating where the next input or output operation will occur. A handle is {\em readable} if it manages only input or both input and output; likewise, it is {\em writable} if it manages only output or both input and output. A handle is {\em open} when first allocated. Once it is closed it can no longer be used for either input or output, though an implementation cannot re-use its storage while references remain to it. Handles are in the @Show@ and @Eq@ classes. The string produced by showing a handle is system dependent; it should include enough information to identify the handle for debugging. A handle is equal according to @==@ only to itself; no attempt is made to compare the internal state of different handles for equality. \subsubsection{Standard Handles} \label{StandardHandles} \index{standard handles} Three handles are allocated during program initialisation. The first two (@stdin@\indextt{stdin} and @stdout@\indextt{stdout}) manage input or output from the \Haskell{} program's standard input or output channel respectively. The third (@stderr@\indextt{stderr}) manages output to the standard error channel. These handles are initially open. \subsubsection{Semi-Closed Handles} \label{SemiClosed} \index{semi-closed handles} The operation "@hGetContents@ hdl"\indextt{hGetContents} (Section~\ref{hGetContents}) puts a handle "hdl" into an intermediate state, {\em semi-closed}. In this state, "hdl" is effectively closed, but items are read from "hdl" on demand and accumulated in a special list returned by @hGetContents@~"hdl". Any operation that fails because a handle is closed, also fails if a handle is semi-closed. The only exception is @hClose@. A semi-closed handle becomes closed: \begin{itemize} \item if @hClose@ is applied to it; \item if an I/O error occurs when reading an item from the handle; \item or once the entire contents of the handle has been read. \end{itemize} 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 evaluated prior to the handle becoming closed. Any I/O errors encountered while a handle is semi-closed are simply discarded. \subsubsection{File locking} Implementations should enforce as far as possible, at least locally to the \Haskell{} process, multiple-reader single-writer locking on files. That is, {\em there may either be many handles on the same file which manage input, or just one handle on the file which manages output}. If any open or semi-closed handle is managing a file for output, no new handle can be allocated for that file. If any open or semi-closed handle is managing a file for input, new handles can only be allocated if they do not manage output. Whether two files are the same is implementation-dependent, but they should normally be the same if they have the same absolute path name and neither has been renamed, for example. {\em Warning}: the @readFile@ operation (Section~\ref{standard-io-functions}) holds a semi-closed handle on the file until the entire contents of the file have been consumed. It follows that an attempt to write to a file (using @writeFile@, for example) that was earlier opened by @readFile@ will usually result in failure with @isAlreadyInUseError@. \indextt{readFile} \indextt{writeFile} \subsection{Opening and Closing Files} \label{OpeningClosing} \subsubsection{Opening Files} \label{Opening} \index{opening a file} \index{creating a file} Computation @openFile@~"file"~"mode"\indextt{openFile} allocates and returns a new, open handle to manage the file "file". % I don't believe this footnote is technically correct -- functions % are never computations IIRC: the computation is the action % that occurs when the function is applied to a state token -- KH % \footnote{We use % the term "computation" instead of "function" here to separate % functions which denote actions in the I/O monad from those outside the monad.} It manages input if "mode"\indextycon{IOMode} is @ReadMode@\indextt{ReadMode}, output if "mode" is @WriteMode@\indextt{WriteMode} or @AppendMode@,\indextt{AppendMode} and both input and output if mode is @ReadWriteMode@.\indextt{ReadWriteMode} If the file does not exist and it is opened for output, it should be created as a new file. If "mode" is @WriteMode@ and the file already exists, then it should be truncated to zero length. Some operating systems delete empty files, so there is no guarantee that the file will exist following an @openFile@ with "mode" @WriteMode@ unless it is subsequently written to successfully. The handle is positioned at the end of the file if "mode" is @AppendMode@, and otherwise at the beginning (in which case its internal I/O position is 0). The initial buffer mode is implementation-dependent. If @openFile@ fails on a file opened for output, the file may still have been created if it did not already exist. {\em Error reporting}: the @openFile@ computation may fail with @isAlreadyInUseError@ if the file is already open and cannot be reopened; @isDoesNotExistError@ if the file does not exist; or @isPermissionError@ if the user does not have permission to open the file. \indextt{isAlreadyInUseError} \indextt{isDoesNotExistError} \indextt{isPermissionError} \subsubsection{Closing Files} \label{Closing} \index{closing a file} Computation @hClose@~"hdl"\indextt{hClose} makes handle "hdl" closed. Before the computation finishes, if "hdl" is writable its buffer is flushed as for @hFlush@. Performing @hClose@ on a handle that has already been closed has no effect; doing so is not an error. All other operations on a closed handle will fail. If @hClose@ fails for any reason, any further operations (apart from @hClose@) on the handle will still fail as if "hdl" had been successfully closed. \subsection{Determining the Size of a File} \label{FileSize} \index{size of file} For a handle "hdl" which is attached to a physical file, @hFileSize@\indextt{hFileSize} "hdl" returns the size of that file in 8-bit bytes ("\geq" 0). \subsection{Detecting the End of Input} \label{EOF} \index{end of file} For a readable handle "hdl", computation @hIsEOF@~"hdl"\indextt{hIsEOF} returns @True@ if no further input can be taken from "hdl"; for a handle attached to a physical file this means that the current I/O position is equal to the length of the file. Otherwise, it returns @False@. The computation @isEOF@\indextt{isEOF} is identical, except that it works only on @stdin@. % The computation may fail with: % \begin{itemize} % \item % @HardwareFault@ % A physical I/O error has occurred. % [@EIO@] % \item % @ResourceExhausted@ % Insufficient resources are available to perform the operation. % [@ENOMEM@] % \item % @IllegalOperation@ % The handle is not open for reading. % \end{itemize} \subsection{Buffering Operations} \label{Buffering} \index{file buffering} Three kinds of buffering are supported: line-buffering, block-buffering or no-buffering. These modes have the following effects. For output, items are written out, or {\em flushed}, from the internal buffer according to the buffer mode: \begin{itemize} \item {\bf line-buffering:} the entire buffer is flushed whenever a newline is output, the buffer overflows, a @hFlush@ is issued, or the handle is closed. \item {\bf block-buffering:} the entire buffer is written out whenever it overflows, a @hFlush@ is issued, or the handle is closed. \item {\bf no-buffering:} output is written immediately, and never stored in the buffer. \end{itemize} An implementation is free to flush the buffer more frequently, but not less frequently, than specified above. The buffer is emptied as soon as it has been written out. Similarly, input occurs according to the buffer mode for handle "hdl". \begin{itemize} \item {\bf line-buffering:} when the buffer for "hdl" is not empty, the next item is obtained from the buffer; otherwise, when the buffer is empty, characters are read into the buffer until the next newline character is encountered or the buffer is full. No characters are available until the newline character is available or the buffer is full. \item {\bf block-buffering:} when the buffer for "hdl" becomes empty, the next block of data is read into the buffer. \item {\bf no-buffering:} the next input item is read and returned. The @hLookAhead@\indextt{hLookAhead} operation (Section~\ref{hLookAhead}) implies that even a no-buffered handle may require a one-character buffer. \end{itemize} For most implementations, physical files will normally be block-buffered and terminals will normally be line-buffered. Computation @hSetBuffering@~"hdl"~"mode"\indextt{hSetBuffering} sets the mode of buffering for handle "hdl" on subsequent reads and writes. \begin{itemize} \item If "mode" is @LineBuffering@, line-buffering is enabled if possible. \item If "mode" is @BlockBuffering@~"size", then block-buffering is enabled if possible. The size of the buffer is "n" items if "size" is @Just @"n" and is otherwise implementation-dependent. \item If "mode" is @NoBuffering@, then buffering is disabled if possible. \end{itemize} If the buffer mode is changed from @BlockBuffering@ or @LineBuffering@ to @NoBuffering@, then \begin{itemize} \item if "hdl" is writable, the buffer is flushed as for @hFlush@; \item if "hdl" is not writable, the contents of the buffer is discarded. \end{itemize} {\em Error reporting}: the @hSetBuffering@ computation may fail with @isPermissionError@ if the handle has already been used for reading or writing and the implementation does not allow the buffering mode to be changed. Computation @hGetBuffering@~"hdl"\indextt{hGetBuffering} returns the current buffering mode for "hdl". The default buffering mode when a handle is opened is implementation-dependent and may depend on the file system object which is attached to that handle. \subsubsection{Flushing Buffers} \label{Flushing} \index{flushing a file buffer} Computation @hFlush@~"hdl"\indextt{hFlush} causes any items buffered for output in handle "hdl" to be sent immediately to the operating system. {\em Error reporting}: the @hFlush@ computation may fail with: @isFullError@ if the device is full; @isPermissionError@ if a system resource limit would be exceeded. It is unspecified whether the characters in the buffer are discarded or retained under these circumstances. \subsection{Repositioning Handles} \label{Seeking} \index{random access files} \index{seeking a file} \subsubsection{Revisiting an I/O Position} Computation @hGetPosn@~"hdl"\indextt{hGetPosn} returns the current I/O position of "hdl" as a value of the abstract type @HandlePosn@. If a call to "@hGetPosn@~h" returns a position "p", then computation @hSetPosn@~"p"\indextt{hSetPosn} sets the position of "h" to the position it held at the time of the call to @hGetPosn@. {\em Error reporting}: the @hSetPosn@ computation may fail with: @isPermissionError@ if a system resource limit would be exceeded. \subsubsection{Seeking to a new Position} Computation @hSeek@~"hdl"~"mode"~"i"\indextt{hSeek} sets the position of handle "hdl" depending on "mode".\indextycon{SeekMode} If "mode" is: \begin{itemize} \item @AbsoluteSeek@:\indextt{AbsoluteSeek} the position of "hdl" is set to "i". \item @RelativeSeek@:\indextt{RelativeSeek} the position of "hdl" is set to offset "i" from the current position. \item @SeekFromEnd@:\indextt{SeekFromEnd} the position of "hdl" is set to offset "i" from the end of the file. \end{itemize} The offset is given in terms of 8-bit bytes. If "hdl" is block- or line-buffered, then seeking to a position which is not in the current buffer will first cause any items in the output buffer to be written to the device, and then cause the input buffer to be discarded. Some handles may not be seekable (see @hIsSeekable@), or only support a subset of the possible positioning operations (for instance, it may only be possible to seek to the end of a tape, or to a positive offset from the beginning or current position). It is not possible to set a negative I/O position, or for a physical file, an I/O position beyond the current end-of-file. {\em Error reporting}: the @hSeek@ computation may fail with: @isPermissionError@ if a system resource limit would be exceeded. \subsection{Handle Properties} \label{Query} The functions @hIsOpen@\indextt{hIsOpen}, @hIsClosed@\indextt{hIsClosed}, @hIsReadable@\indextt{hIsReadable}, @hIsWritable@\indextt{hIsWritable} and @hIsSeekable@\indextt{hIsSeekable} return information about the properties of a handle. Each of these returns @True@ if the handle has the specified property, and @False@ otherwise. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Haskell 1.3 Text Input: LibReadTextIO %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Text Input and Output} \index{reading from a file} %\indextt{LibReadTextIO} Here we define a standard set of input operations for reading characters and strings from text files, using handles. Many of these functions are generalizations of Prelude functions. I/O in the Prelude generally uses @stdin@ and @stdout@; here, handles are explicitly specified by the I/O operation. \subsubsection{Checking for Input} \label{hReady} \label{hWaitForInput} \index{polling a handle for input} Computation @hWaitForInput@~"hdl"~"t"\indextt{hWaitForInput} waits until input is available on handle "hdl". It returns @True@ as soon as input is available on "hdl", or @False@ if no input is available within "t" milliseconds. Computation @hReady@~"hdl"\indextt{hReady} indicates whether at least one item is available for input from handle "hdl". {\em Error reporting}: the @hWaitForInput@ and @hReady@ computations fail with @isEOFError@ if the end of file has been reached. \subsubsection{Reading Input} Computation @hGetChar@~"hdl"\indextt{hGetChar} reads a character from the file or channel managed by "hdl". Computation @hGetLine@~"hdl"\indextt{hGetLine} reads a line from the file or channel managed by "hdl". The Prelude's @getLine@ is a shorthand for @hGetLine stdin@. {\em Error reporting}: the @hGetChar@ computation fails with @isEOFError@ if the end of file has been reached. The @hGetLine@ computation fails with @isEOFError@ if the end of file is encountered when reading the {\em first} character of the line. If @hGetLine@ encounters end-of-file at any other point while reading in a line, it is treated as a line terminator and the (partial) line is returned. \subsubsection{Reading Ahead} \label{hLookAhead} \index{lookahead} Computation @hLookAhead@~"hdl"\indextt{hLookAhead} returns the next character from handle "hdl" without removing it from the input buffer, blocking until a character is available. {\em Error reporting}: the @hLookAhead@ computation may fail with: @isEOFError@ if the end of file has been reached. \subsubsection{Reading The Entire Input} \label{hGetContents} \index{get the contents of a file} Computation @hGetContents@~"hdl"\indextt{hGetContents} returns the list of characters corresponding to the unread portion of the channel or file managed by "hdl", which is made semi-closed. {\em Error reporting}: the @hGetContents@ computation may fail with: @isEOFError@ if the end of file has been reached. \subsubsection{Text Output} Computation @hPutChar@~"hdl"~"c"\indextt{hPutChar} writes the character "c" to the file or channel managed by "hdl". Characters may be buffered if buffering is enabled for "hdl". Computation @hPutStr@~"hdl"~"s"\indextt{hPutStr} writes the string "s" to the file or channel managed by "hdl". Computation @hPrint@~"hdl"~"t"\indextt{hPrint} writes the string representation of "t" given by the @shows@ function to the file or channel managed by "hdl" and appends a newline. {\em Error reporting}: the @hPutChar@, @hPutStr@ and @hPrint@ computations may fail with: @isFull@-@Error@ if the device is full; or @isPermissionError@ if another system resource limit would be exceeded. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Haskell 1.3 Examples %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Examples} \index{input/output examples} Here are some simple examples to illustrate \Haskell{} I/O. \subsubsection{Summing Two Numbers} This program reads and sums two @Integer@s. \bprog @ import IO main = do hSetBuffering stdout NoBuffering putStr "Enter an integer: " x1 <- readNum putStr "Enter another integer: " x2 <- readNum putStr ("Their sum is " ++ show (x1+x2) ++ "\n") where readNum :: IO Integer -- Providing a type signature avoids reliance on -- the defaulting rule to fix the type of x1,x2 readNum = readLn @ \eprog \subsubsection{Copying Files} A simple program to create a copy of a file, with all lower-case characters translated to upper-case. This program will not allow a file to be copied to itself. This version uses character-level I/O. Note that exactly two arguments must be supplied to the program. \bprog @ import IO import System import Char( toUpper ) main = do [f1,f2] <- getArgs h1 <- openFile f1 ReadMode h2 <- openFile f2 WriteMode copyFile h1 h2 hClose h1 hClose h2 copyFile h1 h2 = do eof <- hIsEOF h1 if eof then return () else do c <- hGetChar h1 hPutChar h2 (toUpper c) copyFile h1 h2 @ \eprog An equivalent but much shorter version, using string I/O is: \bprog @ import System import Char( toUpper ) main = do [f1,f2] <- getArgs s <- readFile f1 writeFile f2 (map toUpper s) @ \eprog % Not any more in Haskell 98! % The @~@ used in the patterns above is a necessary consequence of the % @do@-notation which has been used for the I/O operations. In general, % if the pattern on the left of any @<-@ fails to match, the value of % the entire @do@-expression is defined to be the ``zero'' in the % underlying monad. However, since the @IO@ monad has no zero, the @~@ % is required in order to force the pattern to be irrefutable. Without % the @~@, a class error would occur because there is no instance of % @IO@ for class @MonadZero@. \subsection{Library @IO@} \inputHS{lib-code/IO} %**~footer haskell98-report-20080907/report/README0000644000175000017500000001125411345221573016637 0ustar marcotmarcot This is the Haskell 1.4 report, source distribution. This has all files needed to generate either the postscript or the html version of the Haskell 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 report you need lex, perl, latex, makeindex, and dvips. To generate the html report you need Hugs 1.4 (probably any Haskell 1.4 compiler will do). To chage the date on the report, you must change: * haskell.verb (line 429-ish) * index.html (line 8-ish) * html.config (~foot item) Source files for the report: plain-haskell.verb -- Top level of the report Sections of the report: intro.verb lexemes.verb exps.verb decls.verb modules.verb basic.verb io-13.verb standard-prelude.verb syntax-iso.verb literate.verb derived.verb pragmas.verb haskell.bib Extra .verb files: iso-chars.verb -- Some bogus definitions for ISO chars. Probably not -- needed since I removed them from the syntax. layout.verb -- a section on layout repeated in the appendix index-extra.verb -- extra stuff to get indexed (see also's) index-intro.verb -- header for index Haskell source files: Prelude.hs PreludeList.hs PreludeIO.hs PreludeText.hs Figures: classes.ppt -- The original class figure (Powerpoint) classes.eps (*) -- Postscript version of class-fig classes.gif (*) -- For html version cover.cdr -- A nice looking cover for the report cover.eps (*) Html support: html.config -- configuration file for tex.hs. haskell.aux (*) -- The aux file generated by latex; used by html translator haskell.bbl (*) -- used by html translator. Hand edited to add -- html headers at front. prelude-index.idx -- Html file containing index of prelude. #'s are -- expanded by index.hs index.html -- Top level of the html report (hand generated) lambda.gif -- background for title page title.gif -- title graphic Other files: Makefile -- Lots of extra cruft no longer used. haskell.dvi (*) -- in case you just want to run dvips haskell.ind (*) -- is case you don't have makeindex haskell.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! Report any problems to peterson-john@cs.yale.edu Building 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). Run index.hs to generate the function index. You're done. The 'make html' does most of this. There are three files 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. report/prelude-index.idx You will need to edit this a little bit; probably just a few renamings and deleting stuff that lives in the libraries now. Add a few more examples if you're feeling energetic. As to the building process: To build the html report: (using the .aux file and all the .verb files) cd runhugs tex.hs runhugs tex.hs runhugs index.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. Making figures ~~~~~~~~~~~~~~ The classes.eps files, which contains the classes hierarchy figure, is made in Powerpoint, from classses.ppt. To get the .eps file, do the following: * Open classes.ppt * Print.. * Check the print-to-file box, and save as classes.prn * Edit classes.prn Kill the .prn header and footer (before % PS-Adobe), and after %EOF Kill the entire setup code (from BeginSetup to EndSetup) Kill the showpage near the end * Save as classes.eps * Open with Ghostview * Note the coords of the bottom LH and top RH corner, as reported by Ghostview * Re-edit classes.eps, and put those coords in the %BoundingBox line You also need to do Save As.. in Powerpoint, and save the thing as classes.gif, for the HTML version haskell98-report-20080907/report/basic.verb0000644000175000017500000011340411345221573017720 0ustar marcotmarcot% % $Header: /home/cvs/root/haskell-report/report/basic.verb,v 1.17 2003/01/13 13:08:54 simonpj Exp $ % %**The Haskell 98 Report: Predefined Types and Classes %*section 6 %**~header \section{Predefined Types and Classes} \label{basic-types-and-classes} The \Haskell{} Prelude contains predefined classes, types, and functions that are implicitly imported into every Haskell program. In this chapter, we describe the types and classes found in the Prelude. Most functions are not described in detail here as they can easily be understood from their definitions as given in Chapter~\ref{stdprelude}. Other predefined types such as arrays, complex numbers, and rationals are defined in Part~\ref{libraries}. \subsection{Standard Haskell Types} \label{basic-types} These types are defined by the \Haskell{} Prelude. Numeric types are described in Section \ref{numbers}. When appropriate, the \Haskell{} definition of the type is given. Some definitions may not be completely valid on syntactic grounds but they faithfully convey the meaning of the underlying type. \subsubsection{Booleans} \label{booleans} \index{boolean} \bprog @ data Bool = False | True deriving (Read, Show, Eq, Ord, Enum, Bounded) @ \eprog The boolean type @Bool@ is an enumeration. % ; Figure~\ref{prelude-bool} The basic boolean functions are @&&@ (and), @||@ (or), and @not@. The name @otherwise@ is defined as @True@ to make guarded expressions more readable. \label{prelude-bool} \indextycon{Bool} \indextt{False}\indextt{True} \index{""|""|@@{\tt {\char'174}{\char'174}}} \index{&&@@{\tt \&\&}} \indextt{not} \indextt{otherwise} \subsubsection{Characters and Strings} \label{characters} \index{character}\index{string} The character type @Char@\indextycon{Char} is an enumeration whose values represent Unicode characters~\cite{unicode}. % and consists of 16 bit values, conforming to % the Unicode standard~\cite{unicode}. % of which the first 128 % are the ASCII\index{ASCII character set} character set. The lexical syntax for characters is defined in Section~\ref{lexemes-char}; character literals are nullary constructors in the datatype @Char@. Type @Char@ is an instance of the classes @Read@, @Show@, @Eq@, @Ord@, @Enum@, and @Bounded@. The @toEnum@ and @fromEnum@ functions, standard functions from class @Enum@, map characters to and from the @Int@ type. % @Int@ values in the range "[ 0 , 2^{16}-1 ]". Note that ASCII control characters each have several representations in character literals: numeric escapes, ASCII mnemonic escapes, and the @\^@"X" notation. In addition, there are the following equivalences: @\a@ and @\BEL@, @\b@ and @\BS@, @\f@ and @\FF@, @\r@ and @\CR@, @\t@ and @\HT@, @\v@ and @\VT@, and @\n@ and @\LF@. A {\em string} is a list of characters:\nopagebreak[4] \bprog @ type String = [Char] @ \eprog \indexsynonym{String} Strings may be abbreviated using the lexical syntax described in Section~\ref{lexemes-char}. For example, @"A string"@ abbreviates \[ @[ 'A',' ','s','t','r', 'i','n','g']@ \] \subsubsection{Lists} \label{basic-lists} \index{list} \bprog @ data [a] = [] | a : [a] deriving (Eq, Ord) @ \eprog Lists are an algebraic datatype of two constructors, although with special syntax, as described in Section~\ref{lists}. The first constructor is the null list, written `@[]@' (``nil''), \index{[]@@{\tt []} (nil)}% and the second is `@:@' (``cons''). \indextt{:} The module @PreludeList@ (see Section~\ref{preludelist}) defines many standard list functions. Arithmetic sequences \index{arithmetic sequence} and list comprehensions, \index{list comprehension} two convenient syntaxes for special kinds of lists, are described in Sections~\ref{arithmetic-sequences} and \ref{list-comprehensions}, respectively. Lists are an instance of classes @Read@, @Show@, @Eq@, @Ord@, @Monad@, @Functor@, and @MonadPlus@. \subsubsection{Tuples} \label{basic-tuples} \index{tuple} Tuples are algebraic datatypes with special syntax, as defined in Section~\ref{tuples}. Each tuple type has a single constructor. All tuples are instances of @Eq@, @Ord@, @Bounded@, @Read@, and @Show@ (provided, of course, that all their component types are). There is no upper bound on the size of a tuple, but some \Haskell{} implementations may restrict the size of tuples, and limit the instances associated with larger tuples. However, every Haskell implementation must support tuples up to size 15, together with the instances for @Eq@, @Ord@, @Bounded@, @Read@, and @Show@. The Prelude and libraries define tuple functions such as @zip@ for tuples up to a size of 7. The constructor for a tuple is written by omitting the expressions surrounding the commas; thus @(x,y)@ and @(,) x y@ produce the same value. The same holds for tuple type constructors; thus, @(Int,Bool,Int)@ and @(,,) Int Bool Int@ denote the same type. \indextt{(,)} \indextt{(,,)} The following functions are defined for pairs (2-tuples): @fst@, @snd@, @curry@, and @uncurry@. Similar functions are not predefined for larger tuples. \indextt{fst} \indextt{snd} \indextt{curry} \indextt{uncurry} \indextt{zip} \subsubsection{The Unit Datatype} \label{basic-trivial} \bprog @ data () = () deriving (Eq, Ord, Bounded, Enum, Read, Show) @ \eprog The unit datatype @()@ has one non-"\bot" member, the nullary constructor @()@. See also Section~\ref{unit-expression}. \index{trivial type} \subsubsection{Function Types} \index{function} Functions are an abstract type: no constructors directly create functional values. The following simple functions are found in the Prelude: @id@, @const@, @(.)@, @flip@, @($)@, and @until@. \indextt{id} \indextt{const} \indextt{.} \indextt{flip} \indextt{until} \subsubsection{The IO and IOError Types} The @IO@ type serves as a tag for operations (actions) that interact with the outside world. The @IO@ type is abstract: no constructors are visible to the user. @IO@ is an instance of the @Monad@ and @Functor@ classes. Chapter~\ref{io} describes I/O operations. @IOError@ is an abstract type representing errors raised by I/O operations. It is an instance of @Show@ and @Eq@. Values of this type are constructed by the various I/O functions and are not presented in any further detail in this report. The Prelude contains a few I/O functions (defined in Section~\ref{preludeio}), and Part~\ref{libraries} contains many more. \indextycon{IO} \indextycon{IOError} \subsubsection{Other Types} {\small \bprog @ data Maybe a = Nothing | Just a deriving (Eq, Ord, Read, Show) data Either a b = Left a | Right b deriving (Eq, Ord, Read, Show) data Ordering = LT | EQ | GT deriving (Eq, Ord, Bounded, Enum, Read, Show) @ \indextt{Just} \indextt{Nothing} \indextycon{Maybe} \indextt{Left} \indextt{Right} \indextycon{Either} \indextt{LT} \indextt{EQ} \indextt{GT} \indextycon{Ordering} \indextt{maybe} \indextt{either} \eprog } The @Maybe@ type is an instance of classes @Functor@, @Monad@, and @MonadPlus@. The @Ordering@ type is used by @compare@ in the class @Ord@. The functions @maybe@ and @either@ are found in the Prelude. \subsection{Strict Evaluation} \label{strict-eval} \index{$""!@@{\tt {\char'044}{\char'041}}} \index{$@@{\tt {\char'044}}} \indextt{seq} Function application in Haskell is non-strict; that is, a function argument is evaluated only when required. Sometimes it is desirable to force the evaluation of a value, using the @seq@ function: \bprog @ seq :: a -> b -> b @ \eprog The function @seq@ is defined by the equations: \[\ba{l} "@seq@ \bot b = \bot" \\ "@seq@ a b = b, if a \ne \bot" \\ \ea\] @seq@ is usually introduced to improve performance by avoiding unneeded laziness. Strict datatypes (see \index{strictness flags} Section~\ref{strictness-flags}) are defined in terms of the @$!@ operator. However, the provision of @seq@ has important semantic consequences, because it is available {\em at every type}. As a consequence, "\bot" is not the same as @\x -> @ "\bot", since @seq@ can be used to distinguish them. For the same reason, the existence of @seq@ weakens Haskell's parametricity properties. The operator @$!@ is strict (call-by-value) application, and is defined in terms of @seq@. The Prelude also defines the @$@ operator to perform non-strict application. \bprog @ infixr 0 $, $! ($), ($!) :: (a -> b) -> a -> b f $ x = f x f $! x = x `seq` f x @ \eprog The non-strict application operator @$@ may appear redundant, since ordinary application @(f x)@ means the same as @(f $ x)@. However, @$@ has low, right-associative binding precedence, so it sometimes allows parentheses to be omitted; for example: \bprog @ f $ g $ h x = f (g (h x)) @ \eprog It is also useful in higher-order situations, such as @map ($ 0) xs@, or @zipWith ($) fs xs@. \subsection{Standard Haskell Classes} Figure~\ref{standard-classes} shows the hierarchy of \Haskell{} classes defined in the Prelude and the Prelude types that are instances of these classes. \begin{figure}% %*ignore % \epsfbox{class-fig.eps} \includegraphics{classes.eps} % \struthack{11pt} %*endignore %**
Diagram of standard Haskell classes %**

Figure 5

\ecaption{Standard Haskell Classes} \label{standard-classes} \end{figure} Default class method declarations (Section~\ref{classes}) are provided for many of the methods in standard classes. A comment with each @class@ declaration in Chapter~\ref{stdprelude} specifies the smallest collection of method definitions that, together with the default declarations, provide a reasonable definition for all the class methods. If there is no such comment, then all class methods must be given to fully specify an instance. \subsubsection{The Eq Class} \indexclass{Eq} \indextt{==} \indextt{/=} \bprog @ class Eq a where (==), (/=) :: a -> a -> Bool x /= y = not (x == y) x == y = not (x /= y) @ \eprog The @Eq@ class provides equality (@==@) and inequality (@/=@) methods. All basic datatypes except for functions and @IO@ are instances of this class. Instances of @Eq@ can be derived for any user-defined datatype whose constituents are also instances of @Eq@. This declaration gives default method declarations for both @/=@ and @==@, each being defined in terms of the other. If an instance declaration for @Eq@ defines neither @==@ nor @/=@, then both will loop. If one is defined, the default method for the other will make use of the one that is defined. If both are defined, neither default method is used. \subsubsection{The Ord Class} \indexclass{Ord} \indextt{<} \indextt{<=} \indextt{>} \indextt{>=} \indextt{compare} \indextt{max} \indextt{min} \bprog @ class (Eq a) => Ord a where compare :: a -> a -> Ordering (<), (<=), (>=), (>) :: a -> a -> Bool max, min :: a -> a -> a compare x y | x == y = EQ | x <= y = LT | otherwise = GT x <= y = compare x y /= GT x < y = compare x y == LT x >= y = compare x y /= LT x > y = compare x y == GT -- Note that (min x y, max x y) = (x,y) or (y,x) max x y | x <= y = y | otherwise = x min x y | x <= y = x | otherwise = y @ \eprog The @Ord@ class is used for totally ordered datatypes. All basic datatypes except for functions, @IO@, and @IOError@, are instances of this class. Instances of @Ord@ can be derived for any user-defined datatype whose constituent types are in @Ord@. The declared order of the constructors in the data declaration determines the ordering in derived @Ord@ instances. The @Ordering@ datatype allows a single comparison to determine the precise ordering of two objects. The default declarations allow a user to create an @Ord@ instance either with a type-specific @compare@ function or with type-specific @==@ and @<=@ functions. \subsubsection{The Read and Show Classes} \indexsynonym{ReadS} \indexsynonym{ShowS} \indexclass{Read} \indexclass{Show} \indextt{show} \indextt{readsPrec} \indextt{showsPrec} \indextt{readList} \indextt{showList} \bprog @ type ReadS a = String -> [(a,String)] type ShowS = String -> String class Read a where readsPrec :: Int -> ReadS a readList :: ReadS [a] -- ... default decl for readList given in Prelude class Show a where showsPrec :: Int -> a -> ShowS show :: a -> String showList :: [a] -> ShowS showsPrec _ x s = show x ++ s show x = showsPrec 0 x "" -- ... default decl for showList given in Prelude @ \eprog The @Read@ and @Show@ classes are used to convert values to or from strings. The @Int@ argument to @showsPrec@ and @readsPrec@ gives the operator precedence of the enclosing context (see Section~\ref{derived-text}). @showsPrec@ and @showList@ return a @String@-to-@String@ function, to allow constant-time concatenation of its results using function composition. A specialised variant, @show@, is also provided, which uses precedence context zero, and returns an ordinary @String@. The method @showList@ is provided to allow the programmer to give a specialised way of showing lists of values. This is particularly useful for the @Char@ type, where values of type @String@ should be shown in double quotes, rather than between square brackets. Derived instances of @Read@ and @Show@ replicate the style in which a constructor is declared: infix constructors and field names are used on input and output. Strings produced by @showsPrec@ are usually readable by @readsPrec@. All @Prelude@ types, except function types and @IO@ types, are instances of @Show@ and @Read@. (If desired, a programmer can easily make functions and @IO@ types into (vacuous) instances of @Show@, by providing an instance declaration.) \indextt{reads} \indextt{shows} \indextt{read} For convenience, the Prelude provides the following auxiliary functions: \bprog @ reads :: (Read a) => ReadS a reads = readsPrec 0 shows :: (Show a) => a -> ShowS shows = showsPrec 0 read :: (Read a) => String -> a read s = case [x | (x,t) <- reads s, ("","") <- lex t] of [x] -> x [] -> error "PreludeText.read: no parse" _ -> error "PreludeText.read: ambiguous parse" @ \eprog \indextt{shows}\indextt{reads}\indextt{show}\indextt{read} @shows@ and @reads@ use a default precedence of 0. The @read@ function reads input from a string, which must be completely consumed by the input process. \indextt{lex} The function @lex :: ReadS String@, used by @read@, is also part of the Prelude. It reads a single lexeme from the input, discarding initial white space, and returning the characters that constitute the lexeme. If the input string contains only white space, @lex@ returns a single successful ``lexeme'' consisting of the empty string. (Thus @lex ""@ = @[("","")]@.) If there is no legal lexeme at the beginning of the input string, @lex@ fails (i.e. returns @[]@). \subsubsection{The Enum Class} \label{enum-class} \indexclass{Enum} \indextt{toEnum} \indextt{fromEnum} \indextt{enumFrom} \indextt{enumFromThen} \indextt{enumFromTo} \indextt{enumFromThenTo} \bprog @ class Enum a where succ, pred :: a -> a toEnum :: Int -> a fromEnum :: a -> Int enumFrom :: a -> [a] -- [n..] enumFromThen :: a -> a -> [a] -- [n,n'..] enumFromTo :: a -> a -> [a] -- [n..m] enumFromThenTo :: a -> a -> a -> [a] -- [n,n'..m] -- Default declarations given in Prelude @ \eprog Class @Enum@ defines operations on sequentially ordered types. The functions @succ@ and @pred@ return the successor and predecessor, respectively, of a value. The functions @fromEnum@ and @toEnum@ map values from a type in @Enum@ to and from @Int@. The @enumFrom@... methods are used when translating arithmetic sequences (Section~\ref{arithmetic-sequences}). Instances of @Enum@ may be derived for any enumeration type (types whose constructors have no fields); see Chapter~\ref{derived-appendix}. For any type that is an instance of class @Bounded@ as well as @Enum@, the following should hold: \begin{itemize} \item The calls @succ maxBound@ and @pred minBound@ should result in a runtime error. \item @fromEnum@ and @toEnum@ should give a runtime error if the result value is not representable in the result type. For example, @toEnum 7 :: Bool@ is an error. \item @enumFrom@ and @enumFromThen@ should be defined with an implicit bound, thus: \bprog @ enumFrom x = enumFromTo x maxBound enumFromThen x y = enumFromThenTo x y bound where bound | fromEnum y >= fromEnum x = maxBound | otherwise = minBound @ \eprog \end{itemize} The following @Prelude@ types are instances of @Enum@: \begin{itemize} \item Enumeration types: @()@, @Bool@, and @Ordering@. The semantics of these instances is given by Chapter~\ref{derived-appendix}. For example, @[LT..]@ is the list @[LT,EQ,GT]@. \item @Char@: the instance is given in Chapter~\ref{stdprelude}, based on the primitive functions that convert between a @Char@ and an @Int@. For example, @enumFromTo 'a' 'z'@ denotes the list of lowercase letters in alphabetical order. \item Numeric types: @Int@, @Integer@, @Float@, @Double@. The semantics of these instances is given next. \end{itemize} For all four numeric types, @succ@ adds 1, and @pred@ subtracts 1. The conversions @fromEnum@ and @toEnum@ convert between the type and @Int@. In the case of @Float@ and @Double@, the digits after the decimal point may be lost. It is implementation-dependent what @fromEnum@ returns when applied to a value that is too large to fit in an @Int@. For the types @Int@ and @Integer@, the enumeration functions have the following meaning: \begin{itemize} \item The sequence "@enumFrom@~e_1" is the list "@[@e_1@,@e_1+1@,@e_1+2@,@...@]@". \item The sequence "@enumFromThen@~e_1~e_2" is the list "@[@e_1@,@e_1+i@,@e_1+2i@,@...@]@", where the increment, "i", is "e_2-e_1". The increment may be zero or negative. If the increment is zero, all the list elements are the same. \item The sequence "@enumFromTo@~e_1~e_3" is the list "@[@e_1@,@e_1+1@,@e_1+2@,@...e_3@]@". The list is empty if "e_1 > e_3". \item The sequence "@enumFromThenTo@~e_1~e_2~e_3" is the list "@[@e_1@,@e_1+i@,@e_1+2i@,@...e_3@]@", where the increment, "i", is "e_2-e_1". If the increment is positive or zero, the list terminates when the next element would be greater than "e_3"; the list is empty if "e_1 > e_3". If the increment is negative, the list terminates when the next element would be less than "e_3"; the list is empty if "e1 < e_3". \end{itemize} For @Float@ and @Double@, the semantics of the @enumFrom@ family is given by the rules for @Int@ above, except that the list terminates when the elements become greater than "e_3+i/2" for positive increment "i", or when they become less than "e_3+i/2" for negative "i". For all four of these Prelude numeric types, all of the @enumFrom@ family of functions are strict in all their arguments. \subsubsection{The Functor Class} \indexclass{Functor} \indextt{fmap} \index{functor} \bprog @ class Functor f where fmap :: (a -> b) -> f a -> f b @ \eprog The @Functor@ class is used for types that can be mapped over. Lists, @IO@, and @Maybe@ are in this class. Instances of @Functor@ should satisfy the following laws: \[\ba{lcl} @fmap id@&=&@id@\\ @fmap (f . g)@&=&@fmap f . fmap g@\\ \ea\] All instances of @Functor@ defined in the Prelude satisfy these laws. \subsubsection{The Monad Class} \label{monad-class} \indexclass{Monad} \indextt{return} \indextt{fail} \indextt{>>} \indextt{>>=} \index{monad} \bprog @ class Monad m where (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b return :: a -> m a fail :: String -> m a m >> k = m >>= \_ -> k fail s = error s @ \eprog The @Monad@ class defines the basic operations over a {\em monad}. See Chapter~\ref{io} for more information about monads. ``@do@'' expressions provide a convenient syntax for writing monadic expressions (see Section~\ref{do-expressions}). The @fail@ method is invoked on pattern-match failure in a @do@ expression. In the Prelude, lists, @Maybe@, and @IO@ are all instances of @Monad@. The @fail@ method for lists returns the empty list @[]@, for @Maybe@ returns @Nothing@, and for @IO@ raises a user exception in the IO monad (see Section~\ref{io-exceptions}). Instances of @Monad@ should satisfy the following laws: \[\ba{lcl} @return a >>= k@&=&@k a@ \\ @m >>= return@&=&@m@ \\ @m >>= (\x -> k x >>= h)@&=&@(m >>= k) >>= h@\\ \ea\] Instances of both @Monad@ and @Functor@ should additionally satisfy the law: \[\ba{lcl} @fmap f xs@&=&@xs >>= return . f@\\ \ea\] All instances of @Monad@ defined in the Prelude satisfy these laws. The Prelude provides the following auxiliary functions: \bprog @ sequence :: Monad m => [m a] -> m [a] sequence_ :: Monad m => [m a] -> m () mapM :: Monad m => (a -> m b) -> [a] -> m [b] mapM_ :: Monad m => (a -> m b) -> [a] -> m () (=<<) :: Monad m => (a -> m b) -> m a -> m b @ \eprog \indextt{sequence} \index{sequence{\char '137}@@{\tt sequence{\char '137}}} \index{mapM{\char '137}@@{\tt mapM{\char '137}}} \indextt{mapM} \indextt{=<<} \subsubsection{The Bounded Class} \indexclass{Bounded} \indextt{minBound} \indextt{maxBound} @ class Bounded a where minBound, maxBound :: a @ The @Bounded@ class is used to name the upper and lower limits of a type. @Ord@ is not a superclass of @Bounded@ since types that are not totally ordered may also have upper and lower bounds. The types @Int@, @Char@, @Bool@, @()@, @Ordering@, and all tuples are instances of @Bounded@. The @Bounded@ class may be derived for any enumeration type; @minBound@ is the first constructor listed in the @data@ declaration and @maxBound@ is the last. @Bounded@ may also be derived for single-constructor datatypes whose constituent types are in @Bounded@. \subsection{Numbers} \label{numbers} \index{number} \Haskell{} provides several kinds of numbers; the numeric types and the operations upon them have been heavily influenced by %Common Lisp \cite{steele:common-lisp} and Scheme \cite{RRRRS}. Common Lisp and Scheme. Numeric function names and operators are usually overloaded, using several type classes with an inclusion relation shown in Figure~\ref{standard-classes}% %*ignore , page~\pageref{standard-classes}% %*endignore . The class @Num@\indexclass{Num} of numeric types is a subclass of @Eq@\indexclass{Eq}, since all numbers may be compared for equality; its subclass @Real@\indexclass{Real} is also a subclass of @Ord@\indexclass{Ord}, since the other comparison operations apply to all but complex numbers (defined in the @Complex@ library). The class @Integral@\indexclass{Integral} contains integers of both limited and unlimited range; the class @Fractional@\indexclass{Fractional} contains all non-integral types; and the class @Floating@\indexclass{Floating} contains all floating-point types, both real and complex. The Prelude defines only the most basic numeric types: fixed sized integers (@Int@), arbitrary precision integers (@Integer@), single precision floating (@Float@), and double precision floating (@Double@). Other numeric types such as rationals and complex numbers are defined in libraries. In particular, the type @Rational@ is a ratio of two @Integer@ values, as defined in the @Ratio@ library. The default floating point operations defined by the \Haskell{} Prelude do not conform to current language independent arithmetic (LIA) standards. These standards require considerably more complexity in the numeric structure and have thus been relegated to a library. Some, but not all, aspects of the IEEE floating point standard have been accounted for in Prelude class @RealFloat@. The standard numeric types are listed in Table~\ref{standard-numeric-types}. The finite-precision integer type @Int@\indextycon{Int} covers at least the range "[ - 2^{29}, 2^{29} - 1]\/". As @Int@ is an instance of the @Bounded@ class, @maxBound@ and @minBound@ can be used to determine the exact @Int@ range defined by an implementation. %(Figure~\ref{basic-numeric-2}, page~\pageref{basic-numeric-2}) define the limits of %@Int@\indextycon{Int} in each implementation. @Float@\indextycon{Float} is implementation-defined; it is desirable that this type be at least equal in range and precision to the IEEE single-precision type. Similarly, @Double@\indextycon{Double} should cover IEEE double-precision. The results of exceptional conditions (such as overflow or underflow) on the fixed-precision numeric types are undefined; an implementation may choose error ("\bot", semantically), a truncated value, or a special value such as infinity, indefinite, etc. \begin{table}[tb] \[ \bto{|l|l|l|} \hline \multicolumn{1}{|c|}{Type} & \multicolumn{1}{c|}{Class} & \multicolumn{1}{c|}{Description} \\ \hline @Integer@ & @Integral@ & Arbitrary-precision integers \\ @Int@ & @Integral@ & Fixed-precision integers \\ @(Integral a) => Ratio a@ & @RealFrac@ & Rational numbers \\ @Float@ & @RealFloat@ & Real floating-point, single precision \\ @Double@ & @RealFloat@ & Real floating-point, double precision \\ @(RealFloat a) => Complex a@ & @Floating@ & Complex floating-point \\ \hline \eto \] %**

Table 2

\ecaption{Standard Numeric Types} \label{standard-numeric-types} \index{numeric type} \end{table} The standard numeric classes and other numeric functions defined in the Prelude are shown in Figures~\ref{basic-numeric-1}--\ref{basic-numeric-2}. Figure~\ref{standard-classes} shows the class dependencies and built-in types that are instances of the numeric classes. \begin{figure}[tb] \outlinec{ @ class (Eq a, Show a) => Num a where (+), (-), (*) :: a -> a -> a negate :: a -> a abs, signum :: a -> a fromInteger :: Integer -> a class (Num a, Ord a) => Real a where toRational :: a -> Rational class (Real a, Enum a) => Integral a where quot, rem, div, mod :: a -> a -> a quotRem, divMod :: a -> a -> (a,a) toInteger :: a -> Integer class (Num a) => Fractional a where (/) :: a -> a -> a recip :: a -> a fromRational :: Rational -> a class (Fractional a) => Floating a where pi :: a exp, log, sqrt :: a -> a (**), logBase :: a -> a -> a sin, cos, tan :: a -> a asin, acos, atan :: a -> a sinh, cosh, tanh :: a -> a asinh, acosh, atanh :: a -> a @ } %**

Figure 6

\ecaption{Standard Numeric Classes and Related Operations, Part 1} \label{basic-numeric-1} \indexclass{Num} \indextt{+} \indextt{-} \indextt{*} \indextt{negate}\indextt{abs}\indextt{signum} \indextt{fromInteger} \indexclass{Real}\indextt{toRational} \indexclass{Integral} \indextt{quotRem}\indextt{divMod}\indextt{mod}\indextt{div} \indextt{rem}\indextt{quot} \indextt{even}\indextt{odd} \indexclass{Fractional} \indextt{/} \indextt{recip}\indextt{fromRational} \indexclass{Floating}\indextt{pi}\indextt{exp}\indextt{log}\indextt{sqrt} \indextt{**} \indextt{logBase} \indextt{sin}\indextt{cos}\indextt{tan} \indextt{asin}\indextt{acos}\indextt{atan} \indextt{sinh}\indextt{cosh}\indextt{tanh} \indextt{asinh}\indextt{acosh}\indextt{atanh} \end{figure} \begin{figure}[tb] \outlinec{ @ class (Real a, Fractional a) => RealFrac a where properFraction :: (Integral b) => a -> (b,a) truncate, round :: (Integral b) => a -> b ceiling, floor :: (Integral b) => a -> b class (RealFrac a, Floating a) => RealFloat a where floatRadix :: a -> Integer floatDigits :: a -> Int floatRange :: a -> (Int,Int) decodeFloat :: a -> (Integer,Int) encodeFloat :: Integer -> Int -> a exponent :: a -> Int significand :: a -> a scaleFloat :: Int -> a -> a isNaN, isInfinite, isDenormalized, isNegativeZero, isIEEE :: a -> Bool atan2 :: a -> a -> a gcd, lcm :: (Integral a) => a -> a-> a (^) :: (Num a, Integral b) => a -> b -> a (^^) :: (Fractional a, Integral b) => a -> b -> a fromIntegral :: (Integral a, Num b) => a -> b realToFrac :: (Real a, Fractional b) => a -> b @ } %**

Figure 7

\ecaption{Standard Numeric Classes and Related Operations, Part 2} \label{basic-numeric-2} \indexclass{RealFrac}\indextt{properFraction}\indextt{approxRational} \indextt{truncate}\indextt{round} \indextt{ceiling}\indextt{floor} \indexclass{RealFloat} \indextt{floatRadix}\indextt{floatDigits}\indextt{floatRange} \indextt{decodeFloat}\indextt{encodeFloat} \indextt{exponent}\indextt{significand}\indextt{scaleFloat} \indextycon{Int}\indextycon{Integer} \indextt{fromIntegral} \indextt{gcd}\indextt{lcm} \index{^@@{\tt {\char'136}}} % this is ^. Must have 2 spaces after tt! \index{^^@@{\tt {\char'136}{\char'136}}} % this is ^^ \indexclass{RealFrac} \indextycon{Float}\indextycon{Double} \indextt{realToFrac} \indextt{atan2} \end{figure} \subsubsection{Numeric Literals} \label{numeric-literals} The syntax of numeric literals is given in Section~\ref{lexemes-numeric}. An integer literal represents the application of the function @fromInteger@\indextt{fromInteger} to the appropriate value of type @Integer@. Similarly, a floating literal stands for an application of @fromRational@\indextt{fromRational} to a value of type @Rational@ (that is, @Ratio Integer@). Given the typings: \bprog @ fromInteger :: (Num a) => Integer -> a fromRational :: (Fractional a) => Rational -> a @ \eprog\indextt{fromInteger}\indextt{fromRational}% integer and floating literals have the typings @(Num a) => a@ and @(Fractional a) => a@, respectively. Numeric literals are defined in this indirect way so that they may be interpreted as values of any appropriate numeric type. See Section~\ref{default-decls} for a discussion of overloading ambiguity. \subsubsection{Arithmetic and Number-Theoretic Operations} \label{arithmetic-operators} \index{arithmetic operator} The infix class methods @(+)@, \indextt{+} @(*)@, \indextt{*} @(-)@, \indextt{-} and the unary function @negate@\indextt{negate} (which can also be written as a prefix minus sign; see section~\ref{operators}) apply to all numbers. The class methods @quot@\indextt{quot}, @rem@\indextt{rem}, @div@\indextt{div}, and @mod@\indextt{mod} apply only to integral numbers, while the class method @(/)@ \indextt{/} applies only to fractional ones. The @quot@, @rem@, @div@, and @mod@ class methods satisfy these laws if @y@ is non-zero: \[\ba{c} @(x @\bkqB@quot@\bkqA@ y)*y + (x @\bkqB@rem@\bkqA@ y) == x@\\ @(x @\bkqB@div@\bkqA@ y)*y + (x @\bkqB@mod@\bkqA@ y) == x@ \ea\] @`quot`@ is integer division truncated toward zero, while the result of @`div`@ is truncated toward negative infinity. %Note that @quot@ should be used rather than %@div@ to give the semantics of Pascal's @div@. The @quotRem@ class method takes a dividend and a divisor as arguments and returns a (quotient, remainder) pair; @divMod@ is defined similarly: \bprog @ quotRem x y = (x @\bkqB@quot@\bkqA@ y, x @\bkqB@rem@\bkqA@ y) divMod x y = (x @\bkqB@div@\bkqA@ y, x @\bkqB@mod@\bkqA@ y) @ \eprog Also available on integral numbers are the even and odd predicates: \bprog @ even x = x @\bkqB@rem@\bkqA@ 2 == 0 odd = not . even @ \eprog\indextt{even}\indextt{odd} Finally, there are the greatest common divisor and least common multiple functions. @gcd@\indextt{gcd} "x" "y" is the greatest (positive) integer that divides both "x" and "y"; for example @gcd (-3) 6@ = @3@, @gcd (-3) (-6)@ = @3@, @gcd 0 4@ = @4@. @gcd 0 0@ raises a runtime error. @lcm@\indextt{lcm} "x" "y" is the smallest positive integer that both "x" and "y" divide. \subsubsection{Exponentiation and Logarithms} \index{exponentiation}\index{logarithm} The one-argument exponential function @exp@\indextt{exp} and the logarithm function @log@\indextt{log} act on floating-point numbers and use base "e". @logBase@\indextt{logBase} "a" "x" returns the logarithm of "x" in base "a". @sqrt@\indextt{sqrt} returns the principal square root of a floating-point number. There are three two-argument exponentiation operations: @(^)@\index{^@@{\tt {\char'136}}} raises any % number to a nonnegative integer power, @(^^)@\index{^^@@{\tt {\char'136}{\char'136}}} raises a fractional number to any integer power, and @(**)@ \indextt{**} takes two floating-point arguments. The value of "x"@^0@ or "x"@^^0@ is @1@ for any "x", including zero; @0**@"y" is undefined. \subsubsection{Magnitude and Sign} \label{magnitude-sign} \index{magnitude}\index{sign} A number has a {\em magnitude} and a {\em sign}. The functions @abs@\indextt{abs} and @signum@\indextt{signum} apply to any number and satisfy the law: \bprog @ abs x * signum x == x @ \eprog For real numbers, these functions are defined by: \bprog @ abs x | x >= 0 = x | x < 0 = -x signum x | x > 0 = 1 | x == 0 = 0 | x < 0 = -1 @ \eprog \subsubsection{Trigonometric Functions} \index{trigonometric function} Class @Floating@ provides the circular and hyperbolic sine\index{sine}, cosine\index{cosine}, and tangent\index{tangent} functions and their inverses. Default implementations of @tan@, @tanh@, @logBase@, @**@, and @sqrt@ are provided, but implementors are free to provide more accurate implementations. Class @RealFloat@ provides a version of arctangent taking two real floating-point arguments. For real floating "x" and "y", @atan2@\indextt{atan2} "y" "x" computes the angle (from the positive x-axis) of the vector from the origin to the point "(x,y)". @atan2@\indextt{atan2} "y" "x" returns a value in the range @[-pi, pi]@. It follows the Common Lisp semantics for the origin when signed zeroes are supported. @atan2@ "y" @1@, with "y" in a type that is @RealFloat@, should return the same value as @atan@ "y". A default definition of @atan2@ is provided, but implementors can provide a more accurate implementation. The precise definition of the above functions is as in Common Lisp, which in turn follows Penfield's proposal for APL~\cite{penfield:complex-apl}. See these references for discussions of branch cuts, discontinuities, and implementation. \subsubsection{Coercions and Component Extraction} \label{coercion} \index{coercion} The @ceiling@\indextt{ceiling}, @floor@\indextt{floor}, @truncate@\indextt{truncate}, and @round@\indextt{round} functions each take a real fractional argument and return an integral result. \mbox{@ceiling@ "x"} returns the least integer not less than "x", and \mbox{@floor@ "x"}, the greatest integer not greater than "x". \mbox{@truncate@ "x"} yields the integer nearest "x" between "0" and "x", inclusive. \mbox{@round@ "x"} returns the nearest integer to "x", the even integer if "x" is equidistant between two integers. % Keith Wansbrough clarifies the above defn of @round@, % which strangely rounds both 3.5 and 4.5 to 4 % % This is generally considered the most accurate kind of rounding, since it % avoids cumulative errors. If you get lots of values on the 0.5 boundary, % `round up' gives you an error of +0.5 for each, whereas round-to-even gives % you a mean error of zero. % % IEEE floating point does this by default for its basic operations. The function @properFraction@\indextt{properFraction} takes a real fractional number "x" and returns a pair "(n,f)" such that "x = n+f", and: "n" is an integral number with the same sign as "x"; and "f" is a fraction "f" with the same type and sign as "x", and with absolute value less than 1. The @ceiling@, @floor@, @truncate@, and @round@ functions can be defined in terms of @properFraction@. Two functions convert numbers to type @Rational@: @toRational@\indextt{toRational} returns the rational equivalent of its real argument with full precision; @approxRational@\indextt{approxRational} takes two real fractional arguments "x" and "\epsilon" and returns the simplest rational number within "\epsilon" of "x", where a rational $ p/q $ in reduced form is {\em simpler} than another $ p^{\prime} / q^{\prime} $ if $ |p| \leq |p^{\prime}| $ and $ q \leq q^{\prime} $. Every real interval contains a unique simplest rational; in particular, note that $ 0/1 $ is the simplest rational of all.% %\cite[Section 6.5.5]{RRRRS}. The class methods of class @RealFloat@\indexclass{RealFloat} allow efficient, machine-independent access to the components of a floating-point number. The functions @floatRadix@\indextt{floatRadix}, @floatDigits@\indextt{floatDigits}, and @floatRange@\indextt{floatRange} give the parameters of a floating-point type: the radix of the representation, the number of digits of this radix in the significand, and the lowest and highest values the exponent may assume, respectively. The function @decodeFloat@\indextt{decodeFloat} applied to a real floating-point number returns the significand expressed as an @Integer@ and an appropriately scaled exponent (an @Int@). If \mbox{@decodeFloat x@} yields \mbox{@(@"m"@,@"n"@)@}, then @x@ is equal in value to "mb^n", where "b" is the floating-point radix, and furthermore, either "m" and "n" are both zero or else "b^{d-1}<=m a -> b realToFrac :: (Real a, Fractional b) => a -> b @ \eprogNoSkip\indextt{fromIntegral}\indextt{realToFrac} %**~footer % Local Variables: % mode: latex % End: haskell98-report-20080907/report/system.verb0000644000175000017500000000533711345221573020170 0ustar marcotmarcot%**The Haskell 98 Library Report: System functions %**~header \section{System Functions} \outline{ \inputHS{lib-hdrs/System} } \indextycon{ExitCode}\indextt{ExitSuccess}\indextt{ExitFailure} \indextt{getArgs}\indextt{getProgName}\indextt{getEnv} \indextt{system}\indextt{exitWith}\indextt{exitFailure} %% It would be less draconian to return [] for operations %% other than system, exitWith. KH This library describes the interaction of the program with the operating system. Any @System@ 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 must raise an @isIllegalOperation@. The @ExitCode@ type defines the exit codes that a program can return. @ExitSuccess@ indicates successful termination; and @ExitFailure@ "code" indicates program failure with value "code". The exact interpretation of "code" is operating-system dependent. In particular, some values of "code" may be prohibited (for instance, 0 on a POSIX-compliant system). Computation @getArgs@ returns a list of the program's command line arguments (not including the program name)\index{program arguments}. Computation @getProgName@ returns the name of the program as it was invoked\index{program name}. Computation @getEnv@~"var" returns the value of the environment variable "var"\index{environment variables}. If variable "var" is undefined, the @isDoesNotExistError@ exception is raised. Computation @system@~"cmd" returns the exit code produced when the operating system processes the command "cmd"\index{operating system commands}. Computation @exitWith@~"code" terminates the program, returning "code" to the program's caller\index{terminating a program}. Before the program terminates, any open or semi-closed handles are first closed. The caller may interpret the return code as it wishes, but the program should return @ExitSuccess@ to mean normal completion, and @ExitFailure @"n" to mean that the program encountered a problem from which it could not recover. The value @exitFailure@ is equal to @exitWith (ExitFailure @"exitfail"@)@, where "exitfail" is implementation-dependent. @exitWith@ bypasses the error handling in the I/O monad and cannot be intercepted by @catch@. If a program terminates as a result of calling @error@\indextt{error} or because its value is otherwise determined to be "\bot"\index{"\bot"}, then it is treated identically to the computation @exitFailure@. Otherwise, if any program "p" terminates without calling @exitWith@ explicitly, it is treated identically to the computation \bprog @(@"p"@ >> exitWith ExitSuccess) `catch` \ _ -> exitFailure@ \eprog \indextt{catch} %**~footer haskell98-report-20080907/report/haskell98-revised-bugs.html0000644000175000017500000002037111345221573023046 0ustar marcotmarcot Haskell 98 (Revised Report): ERRATA
Haskell 98

Errata in the Revised Haskell 98 Language Report (2003)

The list below gives all known errors in "Haskell 98 Language and Libraries: the Revised Report", published by Cambridge University Press as a book, and also in the Journal of Functional Programming 13(1) (Jan 2003). All page references are to these texts, which may differ slightly from the online versions.
  • [Dec 2005] Page 8, Section 2.2, Lexical Program Structure The production for end-of-line comment appears to permit the character sequence --: to introduce a comment, although it should properly be permissible as a varsym. The production can be fixed by changing it thus:

    comment -> dashes [ any<symbol | : > {any} ] newline

  • [July 2004] Page 32, Section 3.17.2, Informal Semantics of Pattern-Matching, case #6. Case 6 says: "Matching against a constructor using labeled fields is the same as matching ordinary constructor patterns except that the fields are matched in the order they are named in the field list. All fields listed must be declared by the constructor; fields may not be named more than once. Fields not named by the pattern are ignored (matched against _)."

    You could interpret 'field list' to mean the order the fields appear in the pattern, OR, the order in which the fields were declared. The choice of interpretation affects termination behaviour.

    The intention of the Report writers was to use the field order of the pattern, not the declaration. Thus, the Report can be clarified by changing the end of the first sentence above to read "the order they are named in the pattern field list".

  • [Jan 2005] Page 32, Section 3.17.2, Informal Semantics of Pattern-Matching, case #6. Case 6 begins: "Matching against a constructor using labeled fields is ..." To some readers, this could appear to invert the sense of matching, which in all other places is used consistently to mean matching a pattern against a value, not a value against a pattern.

    The proposed fix is to change the start of the sentence to read: "Matching a constructor pattern using labeled fields is ..."

  • [Mar 2008] Page 32, Section 3.17.2, Informal Semantics of Pattern-Matching, case #8. Case 8 says: "Matching ... against a value v succeeds if x >= k, resulting in the binding of n to x - k, and fails otherwise." The variable x should of course be v.

  • [July 2004] Page 55, Section 4.4.2, Fixity Declarations. The operator =<< defined in the Prelude is missing from Table 4.1 - it has precedence 1, right-associative. Also, in the HTML version (but not the printed versions), Table 4.1 is numbered in its caption as Table 2, although it continues to be referred to as Table 4.1 in the text.

  • [May 2003] Page 86, Section 6.3.4, The Enum Class. Section 6.3.4 states: "For all four of these Prelude numeric types, all of the enumFrom family of functions are strict in all their arguments".

    Alas, this contradicts the code for the Prelude in Chapter 8 for Float and Double. In particular, the instances for enumFrom and enumFromThen for Float and Double are defined in terms of numericEnumFrom, numericEnumFromThen, which are not strict (see p113). They both deliver an infinite list even if their argument is undefined.

    The fix is presumably to add a seq to the instances for Float and Double.

  • [June 2003] Page 93, Section 6.4.6, Coercions and Component Extraction. The specification for properFraction does not deal properly with the case where x is zero. Here is a suggested rewording:

    "The function properFraction takes a real fractional number x and returns a pair (n,f) such that x = n+f, and: n is an integral number; f is a fraction with the same type as x and with absolute value less than 1; either n is zero or n has the same sign as x; and either f is zero or f has the same sign as x."

  • [Feb 2008] Page 98, Chapter 7.2, Sequencing I/O Operations. The example using explicit do notation gives unexpected interactive behaviour, due to buffering issues. Either replace uses of putStr with putStrLn, or insert a first line IO.hSetBuffering IO.stdout IO.NoBuffering.

  • [Feb 2003] Page 123, Section 8.2, PreludeText. In the definition of lex make the following changes:
    • Replace isAlpha in the third guard by isIdInit.
    • In the definition of isSingle, remove the underscore '_' from the quoted list.
    • Add the following local definition:
        isIdInit c = isAlpha c || c == '_'
      
    [These changes reflect the fact that an identifier can start with an underscore.]

  • [Sept 2004] Page 136, Chapter 9.5, Context-Free Syntax. The third production for export does not match the production and explanation given earlier in Section 5.2. Replace the qvar in parentheses after qtycls with var.

  • [Aug 2005] Page 152, Chapter 12, Rational Numbers. The function approxRational actually returns the simplest rational number within the given closed interval, not the open interval.

  • [March 2003] Page 170, Chapter 15, Indexing operations. Replace the (bogus) law
      map index (range (l,u)) = [0..rangeSize (l,u)]
    
    by
      map (index (l,u)) (range (l,u)) = [0 .. rangeSize (l,u) - 1]
    

  • [September 2008] Page 187-188, Chapter 17, List utilities. The "generic" functions should behave the same way as the Prelude functions for negative arguments. The ones listed in the report call error, while the Prelude versions simply treat negative numbers as 0. The implementations are replaced by:
    genericTake             :: (Integral a) => a -> [b] -> [b]
    genericTake n _ | n <= 0 = []
    genericTake _ []        =  []
    genericTake n (x:xs)    =  x : genericTake (n-1) xs
    
    genericDrop             :: (Integral a) => a -> [b] -> [b]
    genericDrop n xs | n <= 0 = xs
    genericDrop _ []        =  []
    genericDrop n (_:xs)    =  genericDrop (n-1) xs
    
    genericSplitAt          :: (Integral a) => a -> [b] -> ([b],[b])
    genericSplitAt n xs | n <= 0 =  ([],xs)
    genericSplitAt _ []     =  ([],[])
    genericSplitAt n (x:xs) =  (x:xs',xs'') where
        (xs',xs'') = genericSplitAt (n-1) xs
    

  • [March 2003] Page 194, line -9, Chapter 19, Character utilities. Replace "converts the to the character it encodes" by "converts the string to the character it encodes".

  • [Nov 2006] Page 215, Chapter 21.3.2, Closing Files. In "doing so not an error", insert the verb "is": "doing so is not an error".

  • [July 2003] Index to the online version (only).
    • The type for either is missing.
    • The type for print should be
         print :: Show a => a -> IO ()
      
    • [Oct 2006] The example usage of break is wrong. A correct example might be
          break (>2) [1,2,3] == ([1,2],[3])
      

  • [June 2005] Index to the printed version (only).
    • There is no entry for keywords of the language, which should cross-refer to reservedid.
    • There is no index entry for the where keyword. Relevant page numbers are 10, 13, 56, and 58.

maintainer: Malcolm Wallace, Malcolm.Wallace@cs.york.ac.uk
haskell98-report-20080907/report/h98-revised.html0000644000175000017500000000312711345221573020714 0ustar marcotmarcot Haskell 98: The Revised Report
Haskell 98

Haskell 98: The Revised Report (Jan 2003)

The Haskell 98 Report has undergone an extensive process of revision since its publication in January 1999. This process converged in January 2003, producing the Revised Report.

The Revised Report is published by Cambridge University Press, as a book "Haskell 98 language and libraries: the Revised Report", and also as a Special Issue of the Journal of Functional Programming 13(1) Jan 2003.

The text and sources of the Report are neverthless still available online, as follows:


Simon Peyton Jones, simonpj@microsoft.com
haskell98-report-20080907/report/layout.verb0000644000175000017500000000571011345221573020154 0ustar marcotmarcot% % $Header: /home/cvs/root/haskell-report/report/layout.verb,v 1.1 2001/03/28 14:13:42 simonpj Exp $ % % partain: % in a separate file, because it is included twice (for now); % in intro.verb and syntax.verb % First para added from both sections -- KH % (was other parts for rest in the first sentence of syntax.verb) In the syntax given in the rest of the report, {\em layout lists} are always preceded by the keyword @where@, @let@, @do@, or @of@, and are enclosed within curly braces (@{ }@) with the individual declarations separated by semicolons (@;@). Layout lists usually contain declarations, but @do@ and @case@ introduce lists of other sorts. For example, the syntax of a @let@ expression is: \[ @let {@\ decl_1\ @;@\ decl_2\ @;@\ ...\ @;@\ decl_n\ @} in@\ exp \] \Haskell{} permits the omission of the braces and semicolons by using {\em layout} to convey the same information. This allows both layout-sensitive and -insensitive styles of coding, which can be freely mixed within one program. Because layout is not required, \Haskell{} programs can be straightforwardly produced by other programs. % without worrying about deeply nested layout difficulties. The layout (or ``off-side'') rule\index{off-side rule} takes effect whenever the open brace is omitted after the keyword @where@, @let@, @do@, or @of@. When this happens, the indentation of the next lexeme (whether or not on a new line) is remembered and the omitted open brace is inserted (the whitespace preceding the lexeme may include comments). For each subsequent line, if it contains only whitespace or is indented more, then the previous item is continued (nothing is inserted); if it is indented the same amount, then a new item begins (a semicolon is inserted); and if it is indented less, then the layout list ends (a close brace is inserted). A close brace is also inserted whenever the syntactic category containing the layout list ends; that is, if an illegal lexeme is encountered at a point where a close brace would be legal, a close brace is inserted. The layout rule matches only those open braces that it has inserted; an explicit open brace must be matched by an explicit close brace. Within these explicit open braces, {\em no} layout processing is performed for constructs outside the braces, even if a line is indented to the left of an earlier implicit open brace. Given these rules, a single newline may actually terminate several layout lists. Also, these rules permit: \bprog @ f x = let a = 1; b = 2 g y = exp2 in exp1 @ \eprog making @a@, @b@ and @g@ all part of the same layout list. To facilitate the use of layout at the top level of a module (an implementation may allow several modules may reside in one file), the keyword @module@ and the end-of-file token are assumed to occur in column 0 (whereas normally the first column is 1). Otherwise, all top-level declarations would have to be indented. Section~\ref{layout} gives a more precise definition of the layout rules. haskell98-report-20080907/report/index-intro.verb0000644000175000017500000000030411345221573021071 0ustar marcotmarcotIndex entries that refer to nonterminals in the \Haskell{} syntax are shown in an "italic" font. Code entities are shown in @typewriter@ font. Ordinary index entries are shown in a roman font. haskell98-report-20080907/report/random.verb0000644000175000017500000002263011345221573020117 0ustar marcotmarcot%**The Haskell 98 Library Report: Random Numbers %**~header \section{Random Numbers} \label{random numbers} \outline { \inputHS{lib-hdrs/Random} } The @Random@ library deals with the common task of pseudo-random number generation. The library makes it possible to generate repeatable results, by starting with a specified initial random number generator; or to get different results on each run by using the system-initialised generator, or by supplying a seed from some other source. The library is split into two layers: \begin{itemize} \item A core {\em random number generator} provides a supply of bits. The class @RandomGen@ provides a common interface to such generators. \item The class @Random@ provides a way to extract particular values from a random number generator. For example, the @Float@ instance of @Random@ allows one to generate random values of type @Float@. \end{itemize} \subsection{The @RandomGen@ class, and the @StdGen@ generator} The class @RandomGen@ provides a common interface to random number generators. \bprog @ class RandomGen g where genRange :: g -> (Int,Int) next :: g -> (Int, g) split :: g -> (g, g) -- Default method genRange g = (minBound,maxBound) @ \eprog \indextt{next} \indextt{split} \indextt{genRange} \indextt{RandomGen} \begin{itemize} \item The @genRange@ operation yields the range of values returned by the generator. It is required that: \begin{itemize} \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 argument, and hence the value it returns can be determined only by the instance of @RandomGen@. That in turn allows an implementation to make a single call to @genRange@ to establish a generator's range, without being concerned that the generator returned by (say) @next@ might have a different range to the generator passed to @next@. \item The @next@ operation returns an @Int@ that is uniformly distributed in the range returned by @genRange@ (including both end points), and a new generator. \item The @split@ operation allows one to obtain two independent random number generators. This is very useful in functional programs (for example, when passing a random number generator down to recursive calls), but very little work has been done on statistically robust implementations of @split@ ([1,4] are the only examples we know of). \end{itemize} The @Random@ library provides one instance of @RandomGen@, the abstract data type @StdGen@: \bprog @ data StdGen = ... -- Abstract instance RandomGen StdGen where ... instance Read StdGen where ... instance Show StdGen where ... mkStdGen :: Int -> StdGen @ \eprog \indextycon{StdGen} \indextt{mkStdGen} The @StgGen@ instance of @RandomGen@ has a @genRange@ of at least 30 bits. The result of repeatedly using @next@ should be at least as statistically robust as the ``Minimal Standard Random Number Generator'' described by [2,3]. Until more is known about implementations of @split@, all we require is that @split@ deliver generators that are (a) not identical and (b) independently robust in the sense just given. The @Show@/@Read@ instances of @StdGen@ provide a primitive way to save the state of a random number generator. It is required that @read (show g) == g@. In addition, @read@ may be used to map an arbitrary string (not necessarily one produced by @show@) onto a value of type @StdGen@. In general, the @read@ instance of @StdGen@ has the following properties: \begin{itemize} \item It guarantees to succeed on any string. \item It guarantees to consume only a finite portion of the string. \item Different argument strings are likely to result in different results. \end{itemize} The function @mkStdGen@ provides an alternative way of producing an initial generator, by mapping an @Int@ into a generator. Again, distinct arguments should be likely to produce distinct generators. Programmers may, of course, supply their own instances of @RandomGen@. {\em Implementation warning.} A superficially attractive implementation of @split@ is \bprog @ instance RandomGen MyGen where ... split g = (g, variantOf g) @ \eprog Here, @split@ returns @g@ itself and a new generator derived from @g@. But now consider these two apparently-independent generators: \bprog @ g1 = snd (split g) g2 = snd (split (fst (split g))) @ \eprog If @split@ genuinely delivers independent generators (as specified), then @g1@ and @g2@ should be independent, but in fact they are both equal to @variantOf g@. Implementations of the above form do not meet the specification. \subsection{The @Random@ class} With a source of random number supply in hand, the @Random@ class allows the programmer to extract random values of a variety of types: \bprog @ class Random a where randomR :: RandomGen g => (a, a) -> g -> (a, g) random :: RandomGen g => g -> (a, g) randomRs :: RandomGen g => (a, a) -> g -> [a] randoms :: RandomGen g => g -> [a] randomRIO :: (a,a) -> IO a randomIO :: IO a -- Default methods randoms g = x : randoms g' where (x,g') = random g randomRs = ...similar... randomIO = getStdRandom random randomRIO range = getStdRandom (randomR range) instance Random Int where ... instance Random Integer where ... instance Random Float where ... instance Random Double where ... instance Random Bool where ... instance Random Char where ... @ \eprog \indexclass{Random} \indextt{random} \indextt{randomR} \indextt{randoms} \indextt{randomRs} \indextt{randomIO} \indextt{randomRIO} \begin{itemize} \item @randomR@ takes a range "(lo,hi)" and a random number generator "g", and returns a random value uniformly distributed in the closed interval "[lo,hi]", together with a new generator. It is unspecified what happens if "lo>hi". For continuous types there is no requirement that the values "lo" and "hi" are ever produced, but they may be, depending on the implementation and the interval. % \begin{itemize} % \item For discrete types (such as @Int@ or @Bool@), % ``uniformly distributed'' means that each value is equally likely to occur. % \item For floating-point types (instances of @Floating@, such as @Float@ or @Double@), % the probability of any particular (representable) value "v" % occurring is proportional to "ulp(v)/(h-l)", where "ulp(v)" is the % size of a unit change in the least significant bit position of "v". % \item For continuous types, such as @Rational@, ``uniformly distributed'' means % that the probability distribution of returned values is uniform over the interval. % \end{itemize} % \begin{itemize} % \item For discrete types (such as @Int@ or @Bool@), the range is the closed interval "[l,h]". % \item For fractional types (instances of @Fractional@, such as @Float@ or @Double@), % the range is the semi-closed interval "[l,h)". % \end{itemize} % for discrete types, or if "l \geq h" for fractional types. \item @random@ does the same as @randomR@, but does not take a range. \begin{itemize} \item For bounded types (instances of @Bounded@, such as @Char@), the range is normally the whole type. \item For fractional types, the range is normally the semi-closed interval "[0,1)". \item For @Integer@, the range is (arbitrarily) the range of @Int@. \end{itemize} \item The plural versions, @randomRs@ and @randoms@, produce an infinite list of random values, and do not return a new generator. \item The @IO@ versions, @randomRIO@ and @randomIO@, use the global random number generator (see Section~\ref{global-rng}). \end{itemize} \subsection{The global random number generator} \label{global-rng} There is a single, implicit, global random number generator of type @StdGen@, held in some global variable maintained by the @IO@ monad. It is initialised automatically in some system-dependent fashion, for example, by using the time of day, or Linux's kernel random number generator. To get deterministic behaviour, use @setStdGen@. \bprog @ setStdGen :: StdGen -> IO () getStdGen :: IO StdGen newStdGen :: IO StdGen getStdRandom :: (StdGen -> (a, StdGen)) -> IO a @ \eprog \indextt{setStdGen} \indextt{getStdGen} \indextt{newStdGen} \indextt{getStdRandom} \begin{itemize} \item @getStdGen@ and @setStdGen@ get and set the global random number generator, respectively. \item @newStdGen@ applies @split@ to the current global random generator, updates it with one of the results, and returns the other. \item @getStdRandom@ uses the supplied function to get a value from the current global random generator, and updates the global generator with the new generator returned by the function. For example, @rollDice@ gets a random integer between 1 and 6: \bprog @ rollDice :: IO Int rollDice = getStdRandom (randomR (1,6)) @ \eprog \end{itemize} \subsection*{References} \begin{description} \item[{[1]}] FW Burton and RL Page, ``Distributed random number generation'', Journal of Functional Programming, 2(2):203-212, April 1992. \item[{[2]}] SK Park, and KW Miller, ``Random number generators - good ones are hard to find'', Comm ACM 31(10), Oct 1988, pp1192-1201. \item[{[3]}] DG Carta, ``Two fast implementations of the minimal standard random number generator'', Comm ACM, 33(1), Jan 1990, pp87-88. \item[{[4]}] P Hellekalek, ``Don't trust parallel Monte Carlo'', ACM SIGSIM Simulation Digest 28(1), pp82-89, July 1998. \end{description} The Web site @http://random.mat.sbg.ac.at/@ is a great source of information. %**~efooter haskell98-report-20080907/report/PreludeList.hs0000644000175000017500000002456111345221573020554 0ustar marcotmarcot-- Standard list functions module PreludeList ( map, (++), filter, concat, concatMap, head, last, tail, init, null, length, (!!), foldl, foldl1, scanl, scanl1, foldr, foldr1, scanr, scanr1, iterate, repeat, replicate, cycle, take, drop, splitAt, takeWhile, dropWhile, span, break, lines, words, unlines, unwords, reverse, and, or, any, all, elem, notElem, lookup, sum, product, maximum, minimum, zip, zip3, zipWith, zipWith3, unzip, unzip3) where import qualified Char(isSpace) infixl 9 !! infixr 5 ++ infix 4 `elem`, `notElem` -- Map and append map :: (a -> b) -> [a] -> [b] map f [] = [] map f (x:xs) = f x : map f xs (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) filter :: (a -> Bool) -> [a] -> [a] filter p [] = [] filter p (x:xs) | p x = x : filter p xs | otherwise = filter p xs concat :: [[a]] -> [a] concat xss = foldr (++) [] xss concatMap :: (a -> [b]) -> [a] -> [b] concatMap f = concat . map f -- head and tail extract the first element and remaining elements, -- respectively, of a list, which must be non-empty. last and init -- are the dual functions working from the end of a finite list, -- rather than the beginning. head :: [a] -> a head (x:_) = x head [] = error "Prelude.head: empty list" tail :: [a] -> [a] tail (_:xs) = xs tail [] = error "Prelude.tail: empty list" last :: [a] -> a last [x] = x last (_:xs) = last xs last [] = error "Prelude.last: empty list" init :: [a] -> [a] init [x] = [] init (x:xs) = x : init xs init [] = error "Prelude.init: empty list" null :: [a] -> Bool null [] = True null (_:_) = False -- length returns the length of a finite list as an Int. length :: [a] -> Int length [] = 0 length (_:l) = 1 + length l -- List index (subscript) operator, 0-origin (!!) :: [a] -> Int -> a xs !! n | n < 0 = error "Prelude.!!: negative index" [] !! _ = error "Prelude.!!: index too large" (x:_) !! 0 = x (_:xs) !! n = xs !! (n-1) -- foldl, applied to a binary operator, a starting value (typically the -- left-identity of the operator), and a list, reduces the list using -- the binary operator, from left to right: -- foldl f z [x1, x2, ..., xn] == (...((z `f` x1) `f` x2) `f`...) `f` xn -- foldl1 is a variant that has no starting value argument, and thus must -- be applied to non-empty lists. scanl is similar to foldl, but returns -- a list of successive reduced values from the left: -- scanl f z [x1, x2, ...] == [z, z `f` x1, (z `f` x1) `f` x2, ...] -- Note that last (scanl f z xs) == foldl f z xs. -- scanl1 is similar, again without the starting element: -- scanl1 f [x1, x2, ...] == [x1, x1 `f` x2, ...] foldl :: (a -> b -> a) -> a -> [b] -> a foldl f z [] = z foldl f z (x:xs) = foldl f (f z x) xs foldl1 :: (a -> a -> a) -> [a] -> a foldl1 f (x:xs) = foldl f x xs foldl1 _ [] = error "Prelude.foldl1: empty list" scanl :: (a -> b -> a) -> a -> [b] -> [a] scanl f q xs = q : (case xs of [] -> [] x:xs -> scanl f (f q x) xs) scanl1 :: (a -> a -> a) -> [a] -> [a] scanl1 f (x:xs) = scanl f x xs scanl1 _ [] = [] -- foldr, foldr1, scanr, and scanr1 are the right-to-left duals of the -- above functions. foldr :: (a -> b -> b) -> b -> [a] -> b foldr f z [] = z foldr f z (x:xs) = f x (foldr f z xs) foldr1 :: (a -> a -> a) -> [a] -> a foldr1 f [x] = x foldr1 f (x:xs) = f x (foldr1 f xs) foldr1 _ [] = error "Prelude.foldr1: empty list" scanr :: (a -> b -> b) -> b -> [a] -> [b] scanr f q0 [] = [q0] scanr f q0 (x:xs) = f x q : qs where qs@(q:_) = scanr f q0 xs scanr1 :: (a -> a -> a) -> [a] -> [a] scanr1 f [] = [] scanr1 f [x] = [x] scanr1 f (x:xs) = f x q : qs where qs@(q:_) = scanr1 f xs -- iterate f x returns an infinite list of repeated applications of f to x: -- iterate f x == [x, f x, f (f x), ...] iterate :: (a -> a) -> a -> [a] iterate f x = x : iterate f (f x) -- repeat x is an infinite list, with x the value of every element. repeat :: a -> [a] repeat x = xs where xs = x:xs -- replicate n x is a list of length n with x the value of every element replicate :: Int -> a -> [a] replicate n x = take n (repeat x) -- cycle ties a finite list into a circular one, or equivalently, -- the infinite repetition of the original list. It is the identity -- on infinite lists. cycle :: [a] -> [a] cycle [] = error "Prelude.cycle: empty list" cycle xs = xs' where xs' = xs ++ xs' -- take n, applied to a list xs, returns the prefix of xs of length n, -- or xs itself if n > length xs. drop n xs returns the suffix of xs -- after the first n elements, or [] if n > length xs. splitAt n xs -- is equivalent to (take n xs, drop n xs). take :: Int -> [a] -> [a] take n _ | n <= 0 = [] take _ [] = [] take n (x:xs) = x : take (n-1) xs drop :: Int -> [a] -> [a] drop n xs | n <= 0 = xs drop _ [] = [] drop n (_:xs) = drop (n-1) xs splitAt :: Int -> [a] -> ([a],[a]) splitAt n xs = (take n xs, drop n xs) -- takeWhile, applied to a predicate p and a list xs, returns the longest -- prefix (possibly empty) of xs of elements that satisfy p. dropWhile p xs -- returns the remaining suffix. span p xs is equivalent to -- (takeWhile p xs, dropWhile p xs), while break p uses the negation of p. takeWhile :: (a -> Bool) -> [a] -> [a] takeWhile p [] = [] takeWhile p (x:xs) | p x = x : takeWhile p xs | otherwise = [] dropWhile :: (a -> Bool) -> [a] -> [a] dropWhile p [] = [] dropWhile p xs@(x:xs') | p x = dropWhile p xs' | otherwise = xs span, break :: (a -> Bool) -> [a] -> ([a],[a]) span p [] = ([],[]) span p xs@(x:xs') | p x = (x:ys,zs) | otherwise = ([],xs) where (ys,zs) = span p xs' break p = span (not . p) -- lines breaks a string up into a list of strings at newline characters. -- The resulting strings do not contain newlines. Similary, words -- breaks a string up into a list of words, which were delimited by -- white space. unlines and unwords are the inverse operations. -- unlines joins lines with terminating newlines, and unwords joins -- words with separating spaces. lines :: String -> [String] lines "" = [] lines s = let (l, s') = break (== '\n') s in l : case s' of [] -> [] (_:s'') -> lines s'' words :: String -> [String] words s = case dropWhile Char.isSpace s of "" -> [] s' -> w : words s'' where (w, s'') = break Char.isSpace s' unlines :: [String] -> String unlines = concatMap (++ "\n") unwords :: [String] -> String unwords [] = "" unwords ws = foldr1 (\w s -> w ++ ' ':s) ws -- reverse xs returns the elements of xs in reverse order. xs must be finite. reverse :: [a] -> [a] reverse = foldl (flip (:)) [] -- and returns the conjunction of a Boolean list. For the result to be -- True, the list must be finite; False, however, results from a False -- value at a finite index of a finite or infinite list. or is the -- disjunctive dual of and. and, or :: [Bool] -> Bool and = foldr (&&) True or = foldr (||) False -- Applied to a predicate and a list, any determines if any element -- of the list satisfies the predicate. Similarly, for all. any, all :: (a -> Bool) -> [a] -> Bool any p = or . map p all p = and . map p -- elem is the list membership predicate, usually written in infix form, -- e.g., x `elem` xs. notElem is the negation. elem, notElem :: (Eq a) => a -> [a] -> Bool elem x = any (== x) notElem x = all (/= x) -- lookup key assocs looks up a key in an association list. lookup :: (Eq a) => a -> [(a,b)] -> Maybe b lookup key [] = Nothing lookup key ((x,y):xys) | key == x = Just y | otherwise = lookup key xys -- sum and product compute the sum or product of a finite list of numbers. sum, product :: (Num a) => [a] -> a sum = foldl (+) 0 product = foldl (*) 1 -- maximum and minimum return the maximum or minimum value from a list, -- which must be non-empty, finite, and of an ordered type. maximum, minimum :: (Ord a) => [a] -> a maximum [] = error "Prelude.maximum: empty list" maximum xs = foldl1 max xs minimum [] = error "Prelude.minimum: empty list" minimum xs = foldl1 min xs -- zip takes two lists and returns a list of corresponding pairs. If one -- input list is short, excess elements of the longer list are discarded. -- zip3 takes three lists and returns a list of triples. Zips for larger -- tuples are in the List library zip :: [a] -> [b] -> [(a,b)] zip = zipWith (,) zip3 :: [a] -> [b] -> [c] -> [(a,b,c)] zip3 = zipWith3 (,,) -- The zipWith family generalises the zip family by zipping with the -- function given as the first argument, instead of a tupling function. -- For example, zipWith (+) is applied to two lists to produce the list -- of corresponding sums. zipWith :: (a->b->c) -> [a]->[b]->[c] zipWith z (a:as) (b:bs) = z a b : zipWith z as bs zipWith _ _ _ = [] zipWith3 :: (a->b->c->d) -> [a]->[b]->[c]->[d] zipWith3 z (a:as) (b:bs) (c:cs) = z a b c : zipWith3 z as bs cs zipWith3 _ _ _ _ = [] -- unzip transforms a list of pairs into a pair of lists. unzip :: [(a,b)] -> ([a],[b]) unzip = foldr (\(a,b) ~(as,bs) -> (a:as,b:bs)) ([],[]) unzip3 :: [(a,b,c)] -> ([a],[b],[c]) unzip3 = foldr (\(a,b,c) ~(as,bs,cs) -> (a:as,b:bs,c:cs)) ([],[],[]) haskell98-report-20080907/report/PreludeText.hs0000644000175000017500000001763411345221573020570 0ustar marcotmarcotmodule PreludeText ( ReadS, ShowS, Read(readsPrec, readList), Show(showsPrec, show, showList), reads, shows, read, lex, showChar, showString, readParen, showParen ) where -- The instances of Read and Show for -- Bool, Maybe, Either, Ordering -- are done via "deriving" clauses in Prelude.hs import Char(isSpace, isAlpha, isDigit, isAlphaNum, showLitChar, readLitChar, lexLitChar) import Numeric(showSigned, showInt, readSigned, readDec, showFloat, readFloat, lexDigits) type ReadS a = String -> [(a,String)] type ShowS = String -> String class Read a where readsPrec :: Int -> ReadS a readList :: ReadS [a] -- Minimal complete definition: -- readsPrec readList = readParen False (\r -> [pr | ("[",s) <- lex r, pr <- readl s]) where readl s = [([],t) | ("]",t) <- lex s] ++ [(x:xs,u) | (x,t) <- reads s, (xs,u) <- readl' t] readl' s = [([],t) | ("]",t) <- lex s] ++ [(x:xs,v) | (",",t) <- lex s, (x,u) <- reads t, (xs,v) <- readl' u] class Show a where showsPrec :: Int -> a -> ShowS show :: a -> String showList :: [a] -> ShowS -- Mimimal complete definition: -- show or showsPrec showsPrec _ x s = show x ++ s show x = showsPrec 0 x "" showList [] = showString "[]" showList (x:xs) = showChar '[' . shows x . showl xs where showl [] = showChar ']' showl (x:xs) = showChar ',' . shows x . showl xs reads :: (Read a) => ReadS a reads = readsPrec 0 shows :: (Show a) => a -> ShowS shows = showsPrec 0 read :: (Read a) => String -> a read s = case [x | (x,t) <- reads s, ("","") <- lex t] of [x] -> x [] -> error "Prelude.read: no parse" _ -> error "Prelude.read: ambiguous parse" showChar :: Char -> ShowS showChar = (:) showString :: String -> ShowS showString = (++) showParen :: Bool -> ShowS -> ShowS showParen b p = if b then showChar '(' . p . showChar ')' else p readParen :: Bool -> ReadS a -> ReadS a readParen b g = if b then mandatory else optional where optional r = g r ++ mandatory r mandatory r = [(x,u) | ("(",s) <- lex r, (x,t) <- optional s, (")",u) <- lex t ] -- This lexer is not completely faithful to the Haskell lexical syntax. -- Current limitations: -- Qualified names are not handled properly -- Octal and hexidecimal numerics are not recognized as a single token -- Comments are not treated properly lex :: ReadS String lex "" = [("","")] lex (c:s) | isSpace c = lex (dropWhile isSpace s) lex ('\'':s) = [('\'':ch++"'", t) | (ch,'\'':t) <- lexLitChar s, ch /= "'" ] lex ('"':s) = [('"':str, t) | (str,t) <- lexString s] where lexString ('"':s) = [("\"",s)] lexString s = [(ch++str, u) | (ch,t) <- lexStrItem s, (str,u) <- lexString t ] lexStrItem ('\\':'&':s) = [("\\&",s)] lexStrItem ('\\':c:s) | isSpace c = [("\\&",t) | '\\':t <- [dropWhile isSpace s]] lexStrItem s = lexLitChar s lex (c:s) | isSingle c = [([c],s)] | isSym c = [(c:sym,t) | (sym,t) <- [span isSym s]] | isAlpha c = [(c:nam,t) | (nam,t) <- [span isIdChar s]] | isDigit c = [(c:ds++fe,t) | (ds,s) <- [span isDigit s], (fe,t) <- lexFracExp s ] | otherwise = [] -- bad character where isSingle c = c `elem` ",;()[]{}_`" isSym c = c `elem` "!@#$%&*+./<=>?\\^|:-~" isIdChar c = isAlphaNum c || c `elem` "_'" lexFracExp ('.':c:cs) | isDigit c = [('.':ds++e,u) | (ds,t) <- lexDigits (c:cs), (e,u) <- lexExp t] lexFracExp s = lexExp s lexExp (e:s) | e `elem` "eE" = [(e:c:ds,u) | (c:t) <- [s], c `elem` "+-", (ds,u) <- lexDigits t] ++ [(e:ds,t) | (ds,t) <- lexDigits s] lexExp s = [("",s)] instance Show Int where showsPrec n = showsPrec n . toInteger -- Converting to Integer avoids -- possible difficulty with minInt instance Read Int where readsPrec p r = [(fromInteger i, t) | (i,t) <- readsPrec p r] -- Reading at the Integer type avoids -- possible difficulty with minInt instance Show Integer where showsPrec = showSigned showInt instance Read Integer where readsPrec p = readSigned readDec instance Show Float where showsPrec p = showFloat instance Read Float where readsPrec p = readSigned readFloat instance Show Double where showsPrec p = showFloat instance Read Double where readsPrec p = readSigned readFloat instance Show () where showsPrec p () = showString "()" instance Read () where readsPrec p = readParen False (\r -> [((),t) | ("(",s) <- lex r, (")",t) <- lex s ] ) instance Show Char where showsPrec p '\'' = showString "'\\''" showsPrec p c = showChar '\'' . showLitChar c . showChar '\'' showList cs = showChar '"' . showl cs where showl "" = showChar '"' showl ('"':cs) = showString "\\\"" . showl cs showl (c:cs) = showLitChar c . showl cs instance Read Char where readsPrec p = readParen False (\r -> [(c,t) | ('\'':s,t)<- lex r, (c,"\'") <- readLitChar s]) readList = readParen False (\r -> [(l,t) | ('"':s, t) <- lex r, (l,_) <- readl s ]) where readl ('"':s) = [("",s)] readl ('\\':'&':s) = readl s readl s = [(c:cs,u) | (c ,t) <- readLitChar s, (cs,u) <- readl t ] instance (Show a) => Show [a] where showsPrec p = showList instance (Read a) => Read [a] where readsPrec p = readList -- Tuples instance (Show a, Show b) => Show (a,b) where showsPrec p (x,y) = showChar '(' . shows x . showChar ',' . shows y . showChar ')' instance (Read a, Read b) => Read (a,b) where readsPrec p = readParen False (\r -> [((x,y), w) | ("(",s) <- lex r, (x,t) <- reads s, (",",u) <- lex t, (y,v) <- reads u, (")",w) <- lex v ] ) -- Other tuples have similar Read and Show instances haskell98-report-20080907/report/Prelude.hs0000644000175000017500000004437011345221573017720 0ustar marcotmarcotmodule Prelude ( module PreludeList, module PreludeText, module PreludeIO, Bool(False, True), Maybe(Nothing, Just), Either(Left, Right), Ordering(LT, EQ, GT), Char, String, Int, Integer, Float, Double, Rational, IO, -- These built-in types are defined in the Prelude, but -- are denoted by built-in syntax, and cannot legally -- appear in an export list. -- List type: []((:), []) -- Tuple types: (,)((,)), (,,)((,,)), etc. -- Trivial type: ()(()) -- Functions: (->) Eq((==), (/=)), Ord(compare, (<), (<=), (>=), (>), max, min), Enum(succ, pred, toEnum, fromEnum, enumFrom, enumFromThen, enumFromTo, enumFromThenTo), Bounded(minBound, maxBound), Num((+), (-), (*), negate, abs, signum, fromInteger), Real(toRational), Integral(quot, rem, div, mod, quotRem, divMod, toInteger), Fractional((/), recip, fromRational), Floating(pi, exp, log, sqrt, (**), logBase, sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, asinh, acosh, atanh), RealFrac(properFraction, truncate, round, ceiling, floor), RealFloat(floatRadix, floatDigits, floatRange, decodeFloat, encodeFloat, exponent, significand, scaleFloat, isNaN, isInfinite, isDenormalized, isIEEE, isNegativeZero, atan2), Monad((>>=), (>>), return, fail), Functor(fmap), mapM, mapM_, sequence, sequence_, (=<<), maybe, either, (&&), (||), not, otherwise, subtract, even, odd, gcd, lcm, (^), (^^), fromIntegral, realToFrac, fst, snd, curry, uncurry, id, const, (.), flip, ($), until, asTypeOf, error, undefined, seq, ($!) ) where import PreludeBuiltin -- Contains all `prim' values import UnicodePrims( primUnicodeMaxChar ) -- Unicode primitives import PreludeList import PreludeText import PreludeIO import Ratio( Rational ) infixr 9 . infixr 8 ^, ^^, ** infixl 7 *, /, `quot`, `rem`, `div`, `mod` infixl 6 +, - -- The (:) operator is built-in syntax, and cannot legally be given -- a fixity declaration; but its fixity is given by: -- infixr 5 : infix 4 ==, /=, <, <=, >=, > infixr 3 && infixr 2 || infixl 1 >>, >>= infixr 1 =<< infixr 0 $, $!, `seq` -- Standard types, classes, instances and related functions -- Equality and Ordered classes class Eq a where (==), (/=) :: a -> a -> Bool -- Minimal complete definition: -- (==) or (/=) x /= y = not (x == y) x == y = not (x /= y) class (Eq a) => Ord a where compare :: a -> a -> Ordering (<), (<=), (>=), (>) :: a -> a -> Bool max, min :: a -> a -> a -- Minimal complete definition: -- (<=) or compare -- Using compare can be more efficient for complex types. compare x y | x == y = EQ | x <= y = LT | otherwise = GT x <= y = compare x y /= GT x < y = compare x y == LT x >= y = compare x y /= LT x > y = compare x y == GT -- note that (min x y, max x y) = (x,y) or (y,x) max x y | x <= y = y | otherwise = x min x y | x <= y = x | otherwise = y -- Enumeration and Bounded classes class Enum a where succ, pred :: a -> a toEnum :: Int -> a fromEnum :: a -> Int enumFrom :: a -> [a] -- [n..] enumFromThen :: a -> a -> [a] -- [n,n'..] enumFromTo :: a -> a -> [a] -- [n..m] enumFromThenTo :: a -> a -> a -> [a] -- [n,n'..m] -- Minimal complete definition: -- toEnum, fromEnum -- -- NOTE: these default methods only make sense for types -- that map injectively into Int using fromEnum -- and toEnum. succ = toEnum . (+1) . fromEnum pred = toEnum . (subtract 1) . fromEnum enumFrom x = map toEnum [fromEnum x ..] enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] enumFromThenTo x y z = map toEnum [fromEnum x, fromEnum y .. fromEnum z] class Bounded a where minBound :: a maxBound :: a -- Numeric classes class (Eq a, Show a) => Num a where (+), (-), (*) :: a -> a -> a negate :: a -> a abs, signum :: a -> a fromInteger :: Integer -> a -- Minimal complete definition: -- All, except negate or (-) x - y = x + negate y negate x = 0 - x class (Num a, Ord a) => Real a where toRational :: a -> Rational class (Real a, Enum a) => Integral a where quot, rem :: a -> a -> a div, mod :: a -> a -> a quotRem, divMod :: a -> a -> (a,a) toInteger :: a -> Integer -- Minimal complete definition: -- quotRem, toInteger n `quot` d = q where (q,r) = quotRem n d n `rem` d = r where (q,r) = quotRem n d n `div` d = q where (q,r) = divMod n d n `mod` d = r where (q,r) = divMod n d divMod n d = if signum r == - signum d then (q-1, r+d) else qr where qr@(q,r) = quotRem n d class (Num a) => Fractional a where (/) :: a -> a -> a recip :: a -> a fromRational :: Rational -> a -- Minimal complete definition: -- fromRational and (recip or (/)) recip x = 1 / x x / y = x * recip y class (Fractional a) => Floating a where pi :: a exp, log, sqrt :: a -> a (**), logBase :: a -> a -> a sin, cos, tan :: a -> a asin, acos, atan :: a -> a sinh, cosh, tanh :: a -> a asinh, acosh, atanh :: a -> a -- Minimal complete definition: -- pi, exp, log, sin, cos, sinh, cosh -- asin, acos, atan -- asinh, acosh, atanh x ** y = exp (log x * y) logBase x y = log y / log x sqrt x = x ** 0.5 tan x = sin x / cos x tanh x = sinh x / cosh x class (Real a, Fractional a) => RealFrac a where properFraction :: (Integral b) => a -> (b,a) truncate, round :: (Integral b) => a -> b ceiling, floor :: (Integral b) => a -> b -- Minimal complete definition: -- properFraction truncate x = m where (m,_) = properFraction x round x = let (n,r) = properFraction x m = if r < 0 then n - 1 else n + 1 in case signum (abs r - 0.5) of -1 -> n 0 -> if even n then n else m 1 -> m ceiling x = if r > 0 then n + 1 else n where (n,r) = properFraction x floor x = if r < 0 then n - 1 else n where (n,r) = properFraction x class (RealFrac a, Floating a) => RealFloat a where floatRadix :: a -> Integer floatDigits :: a -> Int floatRange :: a -> (Int,Int) decodeFloat :: a -> (Integer,Int) encodeFloat :: Integer -> Int -> a exponent :: a -> Int significand :: a -> a scaleFloat :: Int -> a -> a isNaN, isInfinite, isDenormalized, isNegativeZero, isIEEE :: a -> Bool atan2 :: a -> a -> a -- Minimal complete definition: -- All except exponent, significand, -- scaleFloat, atan2 exponent x = if m == 0 then 0 else n + floatDigits x where (m,n) = decodeFloat x significand x = encodeFloat m (- floatDigits x) where (m,_) = decodeFloat x scaleFloat k x = encodeFloat m (n+k) where (m,n) = decodeFloat x atan2 y x | x>0 = atan (y/x) | x==0 && y>0 = pi/2 | x<0 && y>0 = pi + atan (y/x) |(x<=0 && y<0) || (x<0 && isNegativeZero y) || (isNegativeZero x && isNegativeZero y) = -atan2 (-y) x | y==0 && (x<0 || isNegativeZero x) = pi -- must be after the previous test on zero y | x==0 && y==0 = y -- must be after the other double zero tests | otherwise = x + y -- x or y is a NaN, return a NaN (via +) -- Numeric functions subtract :: (Num a) => a -> a -> a subtract = flip (-) even, odd :: (Integral a) => a -> Bool even n = n `rem` 2 == 0 odd = not . even gcd :: (Integral a) => a -> a -> a gcd 0 0 = error "Prelude.gcd: gcd 0 0 is undefined" gcd x y = gcd' (abs x) (abs y) where gcd' x 0 = x gcd' x y = gcd' y (x `rem` y) lcm :: (Integral a) => a -> a -> a lcm _ 0 = 0 lcm 0 _ = 0 lcm x y = abs ((x `quot` (gcd x y)) * y) (^) :: (Num a, Integral b) => a -> b -> a x ^ 0 = 1 x ^ n | n > 0 = f x (n-1) x where f _ 0 y = y f x n y = g x n where g x n | even n = g (x*x) (n `quot` 2) | otherwise = f x (n-1) (x*y) _ ^ _ = error "Prelude.^: negative exponent" (^^) :: (Fractional a, Integral b) => a -> b -> a x ^^ n = if n >= 0 then x^n else recip (x^(-n)) fromIntegral :: (Integral a, Num b) => a -> b fromIntegral = fromInteger . toInteger realToFrac :: (Real a, Fractional b) => a -> b realToFrac = fromRational . toRational -- Monadic classes class Functor f where fmap :: (a -> b) -> f a -> f b class Monad m where (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b return :: a -> m a fail :: String -> m a -- Minimal complete definition: -- (>>=), return m >> k = m >>= \_ -> k fail s = error s sequence :: Monad m => [m a] -> m [a] sequence = foldr mcons (return []) where mcons p q = p >>= \x -> q >>= \y -> return (x:y) sequence_ :: Monad m => [m a] -> m () sequence_ = foldr (>>) (return ()) -- The xxxM functions take list arguments, but lift the function or -- list element to a monad type mapM :: Monad m => (a -> m b) -> [a] -> m [b] mapM f as = sequence (map f as) mapM_ :: Monad m => (a -> m b) -> [a] -> m () mapM_ f as = sequence_ (map f as) (=<<) :: Monad m => (a -> m b) -> m a -> m b f =<< x = x >>= f -- Trivial type data () = () deriving (Eq, Ord, Enum, Bounded) -- Not legal Haskell; for illustration only -- Function type -- identity function id :: a -> a id x = x -- constant function const :: a -> b -> a const x _ = x -- function composition (.) :: (b -> c) -> (a -> b) -> a -> c f . g = \ x -> f (g x) -- flip f takes its (first) two arguments in the reverse order of f. flip :: (a -> b -> c) -> b -> a -> c flip f x y = f y x seq :: a -> b -> b seq = ... -- Primitive -- right-associating infix application operators -- (useful in continuation-passing style) ($), ($!) :: (a -> b) -> a -> b f $ x = f x f $! x = x `seq` f x -- Boolean type data Bool = False | True deriving (Eq, Ord, Enum, Read, Show, Bounded) -- Boolean functions (&&), (||) :: Bool -> Bool -> Bool True && x = x False && _ = False True || _ = True False || x = x not :: Bool -> Bool not True = False not False = True otherwise :: Bool otherwise = True -- Character type data Char = ... 'a' | 'b' ... -- Unicode values instance Eq Char where c == c' = fromEnum c == fromEnum c' instance Ord Char where c <= c' = fromEnum c <= fromEnum c' instance Enum Char where toEnum = primIntToChar fromEnum = primCharToInt enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Char)] enumFromThen c c' = map toEnum [fromEnum c, fromEnum c' .. fromEnum lastChar] where lastChar :: Char lastChar | c' < c = minBound | otherwise = maxBound instance Bounded Char where minBound = '\0' maxBound = primUnicodeMaxChar type String = [Char] -- Maybe type data Maybe a = Nothing | Just a deriving (Eq, Ord, Read, Show) maybe :: b -> (a -> b) -> Maybe a -> b maybe n f Nothing = n maybe n f (Just x) = f x instance Functor Maybe where fmap f Nothing = Nothing fmap f (Just x) = Just (f x) instance Monad Maybe where (Just x) >>= k = k x Nothing >>= k = Nothing return = Just fail s = Nothing -- Either type data Either a b = Left a | Right b deriving (Eq, Ord, Read, Show) either :: (a -> c) -> (b -> c) -> Either a b -> c either f g (Left x) = f x either f g (Right y) = g y -- IO type data IO a = ... -- abstract instance Functor IO where fmap f x = x >>= (return . f) instance Monad IO where (>>=) = ... return = ... fail s = ioError (userError s) -- Ordering type data Ordering = LT | EQ | GT deriving (Eq, Ord, Enum, Read, Show, Bounded) -- Standard numeric types. The data declarations for these types cannot -- be expressed directly in Haskell since the constructor lists would be -- far too large. data Int = minBound ... -1 | 0 | 1 ... maxBound instance Eq Int where ... instance Ord Int where ... instance Num Int where ... instance Real Int where ... instance Integral Int where ... instance Enum Int where ... instance Bounded Int where ... data Integer = ... -1 | 0 | 1 ... instance Eq Integer where ... instance Ord Integer where ... instance Num Integer where ... instance Real Integer where ... instance Integral Integer where ... instance Enum Integer where ... data Float instance Eq Float where ... instance Ord Float where ... instance Num Float where ... instance Real Float where ... instance Fractional Float where ... instance Floating Float where ... instance RealFrac Float where ... instance RealFloat Float where ... data Double instance Eq Double where ... instance Ord Double where ... instance Num Double where ... instance Real Double where ... instance Fractional Double where ... instance Floating Double where ... instance RealFrac Double where ... instance RealFloat Double where ... -- The Enum instances for Floats and Doubles are slightly unusual. -- The `toEnum' function truncates numbers to Int. The definitions -- of enumFrom and enumFromThen allow floats to be used in arithmetic -- series: [0,0.1 .. 0.95]. However, roundoff errors make these somewhat -- dubious. This example may have either 10 or 11 elements, depending on -- how 0.1 is represented. instance Enum Float where succ x = x+1 pred x = x-1 toEnum = fromIntegral fromEnum = fromInteger . truncate -- may overflow enumFrom = numericEnumFrom enumFromThen = numericEnumFromThen enumFromTo = numericEnumFromTo enumFromThenTo = numericEnumFromThenTo instance Enum Double where succ x = x+1 pred x = x-1 toEnum = fromIntegral fromEnum = fromInteger . truncate -- may overflow enumFrom = numericEnumFrom enumFromThen = numericEnumFromThen enumFromTo = numericEnumFromTo enumFromThenTo = numericEnumFromThenTo numericEnumFrom :: (Fractional a) => a -> [a] numericEnumFromThen :: (Fractional a) => a -> a -> [a] numericEnumFromTo :: (Fractional a, Ord a) => a -> a -> [a] numericEnumFromThenTo :: (Fractional a, Ord a) => a -> a -> a -> [a] numericEnumFrom = iterate (+1) numericEnumFromThen n m = iterate (+(m-n)) n numericEnumFromTo n m = takeWhile (<= m+1/2) (numericEnumFrom n) numericEnumFromThenTo n n' m = takeWhile p (numericEnumFromThen n n') where p | n' >= n = (<= m + (n'-n)/2) | otherwise = (>= m + (n'-n)/2) -- Lists data [a] = [] | a : [a] deriving (Eq, Ord) -- Not legal Haskell; for illustration only instance Functor [] where fmap = map instance Monad [] where m >>= k = concat (map k m) return x = [x] fail s = [] -- Tuples data (a,b) = (a,b) deriving (Eq, Ord, Bounded) data (a,b,c) = (a,b,c) deriving (Eq, Ord, Bounded) -- Not legal Haskell; for illustration only -- component projections for pairs: -- (NB: not provided for triples, quadruples, etc.) fst :: (a,b) -> a fst (x,y) = x snd :: (a,b) -> b snd (x,y) = y -- curry converts an uncurried function to a curried function; -- uncurry converts a curried function to a function on pairs. curry :: ((a, b) -> c) -> a -> b -> c curry f x y = f (x, y) uncurry :: (a -> b -> c) -> ((a, b) -> c) uncurry f p = f (fst p) (snd p) -- Misc functions -- until p f yields the result of applying f until p holds. until :: (a -> Bool) -> (a -> a) -> a -> a until p f x | p x = x | otherwise = until p f (f x) -- asTypeOf is a type-restricted version of const. It is usually used -- as an infix operator, and its typing forces its first argument -- (which is usually overloaded) to have the same type as the second. asTypeOf :: a -> a -> a asTypeOf = const -- error stops execution and displays an error message error :: String -> a error = primError -- It is expected that compilers will recognize this and insert error -- messages that are more appropriate to the context in which undefined -- appears. undefined :: a undefined = error "Prelude.undefined" haskell98-report-20080907/report/io-13.verb0000644000175000017500000002324411345221573017471 0ustar marcotmarcot%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Haskell 98 Monadic I/O Definition %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %**The Haskell 98 Report: Basic Input/Output %*section 7 %**~header \section{Basic Input/Output} \index{basic input/output} \label{io} The I/O system in \Haskell{} is purely functional, yet has all of the expressive power found in conventional programming languages. To achieve this, \Haskell{} uses a "monad" to integrate I/O operations into a purely functional context. The I/O monad used by \Haskell{} mediates between the "values" natural to a functional language and the "actions" that characterize I/O operations and imperative programming in general. The order of evaluation of expressions in \Haskell{} is constrained only by data dependencies; an implementation has a great deal of freedom in choosing this order. Actions, however, must be ordered in a well-defined manner for program execution -- and I/O in particular -- to be meaningful. \Haskell{}'s I/O monad provides the user with a way to specify the sequential chaining of actions, and an implementation is obliged to preserve this order. \index{monad} The term "monad" comes from a branch of mathematics known as {\em category theory}. From the perspective of a \Haskell{} programmer, however, it is best to think of a monad as an {\em abstract datatype}. In the case of the I/O monad, the abstract values are the "actions" mentioned above. Some operations are primitive actions, corresponding to conventional I/O operations. Special operations (methods in the class @Monad@, see Section~\ref{monad-class}) sequentially compose actions, corresponding to sequencing operators (such as the semicolon) in imperative languages. \subsection{Standard I/O Functions} \label{standard-io-functions} Although \Haskell{} provides fairly sophisticated I/O facilities, as defined in the @IO@ library, it is possible to write many \Haskell{} programs using only the few simple functions that are exported from the Prelude, and which are described in this section. All I/O functions defined here are character oriented. The treatment of the newline character will vary on different systems. For example, two characters of input, return and linefeed, may read as a single newline character. These functions cannot be used portably for binary I/O. In the following, recall that @String@ is a synonym for @[Char]@ (Section~\ref{characters}). \paragraph*{Output Functions} These functions write to the standard output device (this is normally the user's terminal). \bprog @ putChar :: Char -> IO () putStr :: String -> IO () putStrLn :: String -> IO () -- adds a newline print :: Show a => a -> IO () @ \eprog \indextt{putChar} \indextt{putStr} \indextt{putStrLn} \indextt{print} The @print@ function outputs a value of any printable type to the standard output device. Printable types are those that are instances of class @Show@; @print@ converts values to strings for output using the @show@ operation and adds a newline. For example, a program to print the first 20 integers and their powers of 2 could be written as: \bprog @ main = print ([(n, 2^n) | n <- [0..19]]) @ \eprog \paragraph*{Input Functions} These functions read input from the standard input device (normally the user's terminal). \bprog @ getChar :: IO Char getLine :: IO String getContents :: IO String interact :: (String -> String) -> IO () readIO :: Read a => String -> IO a readLn :: Read a => IO a @ \eprog \indextt{interact}% \indextt{readIO}% \indextt{readLn}% \indextt{getChar}% \indextt{getLine}% \indextt{getContents}% The @getChar@ operation raises an exception (Section~\ref{io-exceptions}) on end-of-file; a predicate @isEOFError@ that identifies this exception is defined in the @IO@ library. The @getLine@ operation raises an exception under the same circumstances as @hGetLine@, defined the @IO@ library. The @getContents@ operation returns all user input as a single string, which is read lazily as it is needed. The @interact@ function takes a function of type @String->String@ as its argument. The entire input from the standard input device is passed to this function as its argument, and the resulting string is output on the standard output device. Typically, the @read@ operation from class @Read@ is used to convert the string to a value. The @readIO@ function is similar to @read@ except that it signals parse failure to the I/O monad instead of terminating the program. The @readLn@ function combines @getLine@ and @readIO@. % Removed after extended debate on the Haskell mailing list. % By default, these input functions echo to standard output. % Functions in the I/O library provide full control over echoing. % Lies, all lies The following program simply removes all non-ASCII characters from its standard input and echoes the result on its standard output. (The @isAscii@ function is defined in a library.) \bprog @ main = interact (filter isAscii) @ \eprog \paragraph*{Files} These functions operate on files of characters. Files are named by strings using some implementation-specific method to resolve strings as file names. The @writeFile@ and @appendFile@ functions write or append the string, their second argument, to the file, their first argument. The @readFile@ function reads a file and returns the contents of the file as a string. The file is read lazily, on demand, as with @getContents@. \bprog @ type FilePath = String writeFile :: FilePath -> String -> IO () appendFile :: FilePath -> String -> IO () readFile :: FilePath -> IO String @ \eprog \indextt{writeFile}% \indextt{readFile}% \indextt{appendFile}% \indexsynonym{FilePath}% Note that @writeFile@ and @appendFile@ write a literal string to a file. To write a value of any printable type, as with @print@, use the @show@ function to convert the value to a string first. \bprog @ main = appendFile "squares" (show [(x,x*x) | x <- [0,0.1..2]]) @ \eprog \subsection{Sequencing I/O Operations} \indextt{>>} \indextt{>>=} The type constructor @IO@ is an instance of the @Monad@ class. The two monadic binding functions, methods in the @Monad@ class, are used to compose a series of I/O operations. The @>>@ function is used where the result of the first operation is uninteresting, for example when it is @()@. The @>>=@ operation passes the result of the first operation as an argument to the second operation. \bprog @ (>>=) :: IO a -> (a -> IO b) -> IO b (>>) :: IO a -> IO b -> IO b @ \eprog For example, \bprog @ main = readFile "input-file" >>= \ s -> writeFile "output-file" (filter isAscii s) >> putStr "Filtering successful\n" @ \eprog is similar to the previous example using @interact@, but takes its input from @"input-file"@ and writes its output to @"output-file"@. A message is printed on the standard output before the program completes. \index{do expression} The @do@ notation allows programming in a more imperative syntactic style. A slightly more elaborate version of the previous example would be: \bprog @ main = do putStr "Input file: " ifile <- getLine putStr "Output file: " ofile <- getLine s <- readFile ifile writeFile ofile (filter isAscii s) putStr "Filtering successful\n" @ \eprog The @return@ function is used to define the result of an I/O operation. For example, @getLine@ is defined in terms of @getChar@, using @return@ to define the result: \bprog @ getLine :: IO String getLine = do c <- getChar if c == '\n' then return "" else do s <- getLine return (c:s) @ \eprog \subsection{Exception Handling in the I/O Monad} \index{exception handling} \label{io-exceptions} The I/O monad includes a simple exception handling system. Any I/O operation may raise an exception instead of returning a result. Exceptions in the I/O monad are represented by values of type @IOError@. This is an abstract type: its constructors are hidden from the user. The @IO@ library defines functions that construct and examine @IOError@ values. The only Prelude function that creates an @IOError@ value is @userError@. User error values include a string describing the error. \bprog @ userError :: String -> IOError @ \eprog \indextt{userError}% Exceptions are raised and caught using the following functions: \bprog @ ioError :: IOError -> IO a catch :: IO a -> (IOError -> IO a) -> IO a @ \eprog \indextt{ioError}% \indextt{catch}% The @ioError@ function raises an exception; the @catch@ function establishes a handler that receives any exception raised in the action protected by @catch@. An exception is caught by the most recent handler established by @catch@. These handlers are not selective: all exceptions are caught. Exception propagation must be explicitly provided in a handler by re-raising any unwanted exceptions. For example, in \bprog @ f = catch g (\e -> if IO.isEOFError e then return [] else ioError e) @ \eprog the function @f@ returns @[]@ when an end-of-file exception occurs in @g@; otherwise, the exception is propagated to the next outer handler. The @isEOFError@ function is part of @IO@ library. When an exception propagates outside the main program, the \Haskell{} system prints the associated @IOError@ value and exits the program. The @fail@ method of the @IO@ instance of the @Monad@ class (Section~\ref{monad-class}) raises a @userError@, thus: \bprog @ instance Monad IO where ...bindings for return, (>>=), (>>) fail s = ioError (userError s) @ \eprog \indextt{fail}% The exceptions raised by the I/O functions in the Prelude are defined in Chapter~\ref{IO}. %**~footer haskell98-report-20080907/report/list.verb0000644000175000017500000001560011345221573017611 0ustar marcotmarcot%**The Haskell 98 Library Report: List Utilities %**~header \section{List Utilities} \outline{ \inputHS{lib-hdrs/List} } \outline{ \inputHS{lib-hdrs/List1} } This library defines some lesser-used operations over lists. \subsection{Indexing lists} \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)@. \item @elemIndices val list@\indextt{elemIndices} returns an in-order list of indices, giving the occurrences of @val@ in @list@. \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} There are a number of ``set'' operations defined over the @List@ type. @nub@ (meaning ``essence'') removes duplicates elements from a list. @delete@, @(\\)@, @union@ and @intersect@ (and their @By@ variants) preserve the invariant that their result does not contain duplicates, provided that their first argument contains no duplicates. \begin{itemize} \item @nub@\indextt{nub} removes duplicate elements from a list. For example: \bprog @ nub [1,3,1,4,3,3] = [1,3,4] @ \eprog \item @delete x@\indextt{delete} removes the first occurrence of @x@ from its list argument, e.g., \bprog @ delete 'a' "banana" == "bnana" @ \eprog \item @(\\)@\index{\\\\@@{\tt {\char'134}{\char'134}}} is list difference (non-associative). In the result of @xs \\ ys@, the first occurrence of each element of @ys@ in turn (if any) has been removed from @xs@. Thus, @(xs ++ ys) \\ xs == ys@. \item @union@\indextt{union} is list union, e.g., \bprog @ "dog" `union` "cow" == "dogcw" @ \eprog \item @intersect@\indextt{intersect} is list intersection, e.g., \bprog @ [1,2,3,4] `intersect` [2,4,6,8] == [2,4] @ \eprog \end{itemize} \subsection{List transformations} \begin{itemize} \item @intersperse sep@\indextt{intersperse} inserts @sep@ between the elements of its list argument, e.g., \bprog @ intersperse ',' "abcde" == "a,b,c,d,e" @ \eprog \item @transpose@\indextt{transpose} transposes the rows and columns of its argument, e.g., \bprog @ transpose [[1,2,3],[4,5,6]] == [[1,4],[2,5],[3,6]] @ \eprog \item @partition@\indextt{partition} takes a predicate and a list and returns a pair of lists: those elements of the argument list that do and do not satisfy the predicate, respectively; i.e., \bprog @ partition p xs == (filter p xs, filter (not . p) xs) @ \eprog \item @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 example \bprog @ group "Mississippi" == ["M","i","ss","i","ss","i","pp","i"] @ \eprog \item @inits@\indextt{inits} returns the list of initial segments of its argument list, shortest first. \bprog @ inits "abc" == ["","a","ab","abc"] @ \eprog \item @tails@\indextt{tails} returns the list of all final segments of its argument list, longest first. \bprog @ tails "abc" == ["abc", "bc", "c",""] @ \eprog \item @mapAccumL f s l@\indextt{mapAccumL} applies @f@ to an accumulating ``state'' parameter @s@ and to each element of @l@ in turn. \item @mapAccumR@\indextt{mapAccumR} is similar to @mapAccumL@ except that the list is processed from right-to-left rather than left-to-right. \end{itemize} \subsection{@unfoldr@} The @unfoldr@ function is a ``dual'' to @foldr@: while @foldr@ reduces a list to a summary value, @unfoldr@ builds a list from a seed value. For example: \bprog @ iterate f == unfoldr (\x -> Just (x, f x)) @ \eprog In some cases, @unfoldr@ can undo a @foldr@ operation: \bprog @ unfoldr f' (foldr f z xs) == xs @ \eprog if the following holds: \bprog @ f' (f x y) = Just (x,y) f' z = Nothing @ \eprog \subsection{Predicates} @isPrefixOf@ and @isSuffixOf@ check whether the first argument is a prefix (resp. suffix) of the second argument. \subsection{The ``@By@'' operations} By convention, overloaded functions have a non-overloaded counterpart whose name is suffixed with ``@By@''. For example, the function @nub@ could be defined as follows: \bprog @ nub :: (Eq a) => [a] -> [a] nub [] = [] nub (x:xs) = x : nub (filter (\y -> not (x == y)) xs) @ \eprog However, the equality method may not be appropriate in all situations. The function: \bprog @ nubBy :: (a -> a -> Bool) -> [a] -> [a] nubBy eq [] = [] nubBy eq (x:xs) = x : nubBy eq (filter (\y -> not (eq x y)) xs) @ \eprog allows the programmer to supply their own equality test. When the ``@By@'' function replaces an @Eq@ context by a binary predicate, the predicate is assumed to define an equivalence; when the ``@By@'' 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@, @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. % Several of the functions defined here are derivatives of, or % related to, Prelude functions. These functions are % @elem@, @maximum@, @minimum@, @zip@, @zip3@, @zipWith@, % @zipWith3@, @unzip@, @unzip3@, % [according to Keith] @take@, @drop@, @splitAt@, @index@, @replicate@. \subsection{The ``@generic@'' operations} The prefix ``@generic@'' indicates an overloaded function that is a generalised version of a @Prelude@ function. For example, \bprog @ genericLength :: Integral a => [b] -> a @ \eprog is a generalised version of @length@. The ``@generic@'' operations are as follows: @genericLength@, @genericTake@, @genericDrop@, @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}} \label{List} \inputHS{lib-code/List} %**~footer haskell98-report-20080907/libraries/0000755000175000017500000000000011345221573016415 5ustar marcotmarcothaskell98-report-20080907/libraries/ratio.verb0000644000175000017500000000421311345221573020413 0ustar marcotmarcot%**The Haskell 98 Library Report: Rational Numbers %**~header \section{Rational Numbers} \index{rational numbers} \outline{ \inputHS{headers/Ratio} } For each @Integral@ type $t$, there is a type @Ratio@\indextycon{Ratio} $t$ of rational pairs with components of type $t$. The type name @Rational@\indexsynonym{Rational} is a synonym for @Ratio Integer@. @Ratio@ is an instance of classes @Eq@, @Ord@, @Num@, @Real@, @Fractional@, @RealFrac@, @Enum@, @Read@, and @Show@. In each case, the instance for $@Ratio@~t$ simply ``lifts'' the corresponding operations over $t$. If $t$ is a bounded type, the results may be unpredictable; for example @Ratio Int@ may give rise to integer overflow even for rational numbers of small absolute size. The operator @(%)@\index{%@@{\tt {\char'045}}} forms the ratio of two integral numbers, reducing the fraction to terms with no common factor and such that the denominator is positive. The functions @numerator@\indextt{numerator} and @denominator@\indextt{denominator} extract the components of a ratio; these are in reduced form with a positive denominator. @Ratio@ is an abstract type. For example, @12 % 8@ is reduced to 3/2 and @12 % (-8)@ is reduced to (-3)/2. The @approxRational@ function, applied to two real fractional numbers @x@ and @epsilon@, returns the simplest rational number within the open interval "(@x@-@epsilon@, @x@+@epsilon@)". A rational number "n/d" in reduced form is said to be simpler than another "n'/d'" if "|n| \leq |n'|" and "d \leq d'". Note that it can be proved that any real interval contains a unique simplest rational. %% Deleted the following -- this is implementation detail -- KH/AD. % ; here, for simplicity, we assume a closed rational % interval. If such an interval includes at least one whole number, then % the simplest rational is the absolutely least whole number. Otherwise, % the bounds are of the form "q/1 + r/d" and "q/1 + r'/d'", where "|r| < d" % and "|r'| < d'", and the simplest rational is "q/1" + the reciprocal of % the simplest rational between "d'/r'" and "d/r". \clearpage \subsection{Library {\tt Ratio}} \label{Ratio} \inputHS{code/Ratio} %**~footer haskell98-report-20080907/libraries/library.verb0000644000175000017500000004140511345221573020745 0ustar marcotmarcot% % $Header: /home/cvs/root/haskell-report/libraries/library.verb,v 1.13 2002/12/02 11:22:00 simonpj Exp $ % % NOTE:-------------------------------------------------------------- % The formatting of this report and the ``new font selection scheme'' % for LaTeX don't agree w/ each other. Using an ``oldlfont'' style % option may help. % ------------------------------------------------------------------- % % ------------------------------------------------------------------- % formatting for ONE-SIDED printing: % * De-comment the \documentstyle, etc., here; comment out the % two-sided ones below. % * Change the definition of \startnewstuff (below). % * Copy the pre-built index file for one-sided printing: % cp haskell.ind.one-sided haskell.ind % * Comment out the "twosidefix" stuff from Joe Fasel, just below. % * If you don't have "makeindex", make the adjustments % listed in the README file. % * Run "make haskell.dvi" several times (three, at most) to be % sure that cross-references stabilise. [For the 1.1 report, % one run should be enough.] \documentstyle[twoside,11pt,makeidx]{article} \oddsidemargin=.25in \evensidemargin=.25in % formatting for double-sided %\documentstyle[twoside,11pt,makeidx]{article} % Inverted for SIGPLAN -- Page 1 is a LEFT page!! %\evensidemargin=0in %\oddsidemargin=.5in %\evensidemargin=.5in %\oddsidemargin=0in %--------------------------------------------------------------------- % Joe Fasel said this "twosidefix" is necessary if you really % have a two-sided printer: % (note: double @@'s for verbatim-ery) \makeatletter \def\titlepage{\@@restonecolfalse\if@@twocolumn\@@restonecoltrue\onecolumn \else \newpage \fi \thispagestyle{empty}\c@@page\m@@ne} \def\endtitlepage{\if@@twoside\newpage\thispagestyle{empty}\hbox{} \else \c@@page\@@z \fi \if@@restonecol\twocolumn \else \newpage \fi} \makeatother %--------------------------------------------------------------------- % the major sections have \cleardoublepages between them % if you want those between EVERY section, change the % following defn: \newcommand{\startnewsection}{\clearpage} % % if doing one-sided printing, change this defn to % be just "\clearpage": \newcommand{\startnewstuff}{\clearpage} %\newcommand{\startnewstuff}{\cleardoublepage} % keep some pages from looking unbelievably appalling \raggedbottom % Fix those ugly floating figures. \renewcommand{\floatpagefraction}{0.1} \renewcommand{\textfraction}{0.1} \renewcommand{\topfraction}{1.0} \renewcommand{\bottomfraction}{1.0} % table of contents: show only down to subsections \setcounter{tocdepth}{2} % general formatting \textheight=8.5in \textwidth=6.0in \topmargin=0in \pagestyle{headings} \makeindex % an extra thing for makeindex \newcommand{\hseealso}[2]{{\em see also\/} #1} % NEWCOMMANDS % general \newcommand{\folks}[1]{\begin{quote}\sf#1\end{quote}} \newcommand{\sectionpart}[1]{\vspace{2 ex}\noindent{\bf #1}} \newcommand{\bq}{\begin{quote}} \newcommand{\eq}{\end{quote}} \newcommand{\bt}{\begin{tabular}} \newcommand{\et}{\end{tabular}} \newcommand{\bi}{\begin{itemize}} \newcommand{\ei}{\end{itemize}} \newcommand{\struthack}[1]{\rule{0pt}{#1}} \newcommand{\inputHS}{\input} \newcommand{\ignorehtml}[1]{#1} %\newcommand{\ToDo}[1]{} \newcommand{\ToDo}[1]{({\bf $\spadesuit$ ToDo:} {\em #1})} \newcommand{\WeSay}[1]{} %\newcommand{\WeSay}[1]{({\bf $\clubsuit$ YaleSays:} {\em #1})} \newcommand{\anchor}[2]{#2} % indexing \newcommand{\indextt}[1]{\index{#1@@{\tt #1}}} \newcommand{\indexsyn}[1]{\index{#1@@{\it #1}}} \newcommand{\indexmodule}[1]{\index{#1@@{\tt #1} (module)}} \newcommand{\indextycon}[1]{\index{#1@@{\tt #1} (datatype)}} \newcommand{\indexsynonym}[1]{\index{#1@@{\tt #1} (type synonym)}} \newcommand{\indexnote}[1]{#1n} \makeatletter \def\theindex{\@@restonecoltrue\if@@twocolumn\@@restonecolfalse\fi \columnseprule \z@@ \columnsep 35pt\twocolumn[\section*{Index} \addcontentsline{toc}{section}{Index} \input{index-intro}\vskip 20pt] \@@mkboth{INDEX}{INDEX}\thispagestyle{plain}\parindent\z@@ \parskip\z@@ plus .3pt\relax\let\item\@@idxitem } \makeatother % outlined figures \newcommand{\ecaption}[1]{\vspace{-1 ex}\caption{#1}\vspace{1 ex}} % partain fiddled here... % also had to change two lines in verbatim.lex from %{nl}"|"{sp} { printf ("$\\\\ \n$\\it "); % printf ("$\\>\\makebox[3em]{$|$}$\\it "); } % to % %{nl}"|"{sp} { printf ("$\\\\ \n$\\it "); % printf ("$\\>\\makebox[3.5em]{$|$}$\\it "); } % so things would still line up. Oh what a hack. % %\newcommand{\outline}{\outlinewidth{1.0}} %\newcommand{\outlinewidth}[2]{ %\begin{center} %\fbox{ \begin{minipage}{#1\textwidth} %\vspace{1 ex} %#2 %\end{minipage} } %\vspace{1 ex} %\end{center} %} % 6.0in (\textwidth) - 15pt (overfullness) ~=~ 415pt \newcommand{\outline}[1]{% \begin{center} \fbox{ \begin{minipage}{415pt} \vspace{1 ex} #1 \end{minipage} } \vspace{1 ex} \end{center} } \newcommand{\outlinec}{\outline} % Centered outlines in html % haskell code % partain fiddled here... % \newcommand{\bprog}{\par \begin{tabular}{|l} % \mbox \bgroup \begin{minipage} {\textwidth} } % 6.0in (\textwidth) - 17pt (\parindent) ~=~ 412pt %\newcommand{\bprog}{\par \begin{tabular}{@@{}l@@{}} % \mbox \bgroup \begin{minipage} {412pt} } %\newcommand{\eprog}{\end{minipage} % \egroup % \end{tabular}\\[\parskip]} % 17pt is \parindent % this method gives a 17pt indent in _all_ situations \newcommand{\bprog}{% \par\noindent\begin{tabular}{@@{\hspace*{17pt}}l@@{}}} \newcommand{\eprog}{% \end{tabular}\\[\parskip]} \newcommand{\eprogNoSkip}{% \end{tabular}} % % variants for stdprelude; don't indent, and skip a little more \newcommand{\bprogB}{% \begin{tabular}{@@{}l@@{}}} \newcommand{\eprogB}{% \end{tabular}\\[0.6\baselineskip]} %special characters \newcommand{\bkq}{\mbox{\it \char'022}} % (syntax) backquote char \newcommand{\bkqB}{\bkq} % (syntax) backquote char (Before) \newcommand{\bkqA}{\hspace{-.2em}\mbox{\it \char'022}}% (syntax) backquote char (After) %\newcommand{\fwq}{\mbox{\it \char'023}} % (syntax) (forward) quote char % math formatting \newcommand{\ba}{\begin{array}} \newcommand{\ea}{\end{array}} \newcommand{\mc}{\multicolumn} \newcommand{\pile}[1]{\ba[t]{@@{}l@@{}} #1 \ea} \newcommand{\eqn}[1]{\ba[t]{@@{}lcl@@{}} #1 \ea} \newcommand{\equate}[1]{\[\eqn{#1}\]} \newcommand{\la}{\leftarrow} \newcommand{\ra}{\rightarrow} \newcommand{\sq}[1]{[\,#1\,]} \newcommand{\ab}[1]{\langle#1\rangle} \newcommand{\ablarge}[1]{\langle \pile{#1\,\rangle}} \newcommand{\lb}{[\![} \newcommand{\rb}{]\!]} \newcommand{\db}[1]{\lb#1\rb} \newcommand{\ti}[1]{\mbox{{\it #1}}} \newcommand{\tr}[1]{\mbox{{\rm #1}}} \newcommand{\tb}[1]{\mbox{{\bf #1}}} \newcommand{\x}{\times} \newcommand{\lam}{\lambda} \newcommand{\kr}{\kappa_{\rho}} \newcommand{\syneq}{\rightarrow} % denotational semantics \newcommand{\denote}[3]{\[\ba{c} {\cal #1} : #2 \\[1 ex] #3 \ea\]} \newcommand{\den}[2]{{\cal #1}\db{#2}\,} \newcommand{\A}{\den{A}} \newcommand{\B}{\den{B}} \newcommand{\D}{\den{D}} \newcommand{\E}{\den{E}} \newcommand{\F}{\den{F}} \newcommand{\G}{\den{G}} \newcommand{\I}{\den{I}} %%% \renewcommand{\L}{\den{L}} \newcommand{\LE}{\den{L_E}} \newcommand{\LH}{\den{L_H}} \newcommand{\M}{\den{M}} %%% \renewcommand{\O}{\den{O}} \renewcommand{\P}{\den{P}} \newcommand{\Pbot}{\den{P_{\bot}}} \newcommand{\Q}{\den{Q}} \newcommand{\R}{\den{R}} \renewcommand{\S}{\den{S}} \newcommand{\V}{\den{V}} \newcommand{\W}{\den{W}} \newcommand{\T}[2]{\den{T}{#1}\,\db{#2}} % meta language \newcommand{\PP}{\den{P'}} \newcommand{\PS}{\den{P_S}} \newcommand{\otherwise}{\quad\tr{otherwise}} \newcommand{\case}[2]{\pile{ \tr{case}\ (#1)\ \tr{of} \\ \ba{@@{\quad}l@@{\ \ra\ }l@@{}} #2 \ea}} \newcommand{\where}[2]{#1 \quad\tr{where}\quad #2} \newcommand{\wherelarge}[2]{\pile{#1 \\ \tr{where} \\ \eqn{#2}}} \newcommand{\cond}[3]{#1 \ra #2,\ #3} \newcommand{\condlarge}[1]{\ba[t]{@@{}l@@{\ \ra\ }l@@{}} #1 \ea} \newcommand{\range}[2]{{}_{#1}^{#2}\,} % semantic operators \newcommand{\concat}{\frown} \newcommand{\seq}[1]{\ti{List}\ #1} \newcommand{\opt}[1]{\widetilde{#1}} \newcommand{\ov}{\opt{v}} \newcommand{\fail}{\ti{none}} \newcommand{\nonfail}{\ti{proper}} \newcommand{\sym}{\bigtriangledown} \newcommand{\pri}{\mathbin{\vec{\sym}}} \newcommand{\mrg}{\mathbin{\dot{\sym}}} \newcommand{\Sym}{\mathbin{\nabla}} \newcommand{\Pri}{\mathbin{\vec{\Sym}}} \newcommand{\Mrg}{\mathbin{\dot{\Sym}}} \newcommand{\optSym}{\mathbin{\opt{\Sym}}} \newcommand{\optodot}{\mathbin{\opt{\odot}}} \newcommand{\proj}{\mid} \newcommand{\restrict}{\setminus} \newcommand{\sel}[4]{\ti{sel}_{#3#2}\ #4} \newcommand{\bindnone}{\ti{bindnone}} \newcommand{\bindvar}[2]{\ti{bindvar}\ \db{#1}\ #2} \newcommand{\bindcon}[2]{\ti{bindcon}\ \db{#1}\ #2} \newcommand{\bindconlarge}[4]{ #4\ \bindcon{#1}{\ablarge{ #2, \\ #3}}} \newcommand{\bindmod}[2]{\ti{bindmod}\ \db{#1}\ #2} \newcommand{\lookupval}[2]{\ti{lookupval}\ #1\ \db{#2}} %%% NEW \newcommand{\lookupcon}[1]{\ti{lookupcon}\ \db{#1}} %%% NEW \newcommand{\lookupdecon}[2]{\ti{lookupdecon}\ #1\ \db{#2}} %%% NEW % used in static.verb \newcommand{\TT}{\den{T_T}} \newcommand{\TA}{\den{T_A}} \newcommand{\TB}{\den{T_B}} \newcommand{\TD}{\den{T_D}} \newcommand{\TDA}{\den{T_{D_A}}} \newcommand{\TDB}{\den{T_{D_B}}} \newcommand{\TDP}{\den{T_{P_D}}} \newcommand{\TE}{\den{T_E}} \newcommand{\TLE}{\den{T_{L_E}}} \newcommand{\TLH}{\den{T_{L_H}}} %%% \newcommand{\TG}{\den{T_G}} \newcommand{\TQ}{\den{T_Q}} %%% \newcommand{\TR}{\den{T_R}} \newcommand{\TF}{\den{T_F}} \newcommand{\TFA}{\den{T_F'}} \newcommand{\TP}{\den{T_P}} \newcommand{\TPP}{\den{T_P'}} \newcommand{\TPS}{\den{T_{PS}}} \newcommand{\MGU}{\ti{MGU}} \newcommand{\TI}{\den{T_I}} \newcommand{\TL}{\den{T_L}} \newcommand{\TM}{\den{T_M}} %%% \newcommand{\TO}{\den{T_O}} \newcommand{\TS}{\den{T_S}} \newcommand{\TV}{\den{T_V}} \newcommand{\tenvm}{\ddot{\nabla}} \renewcommand{\tb}[1]{\triangleright#1\triangleleft} \newcommand{\unbindvar}[2]{\ti{unbindvar}\ \db{#1}\ #2} \newcommand{\unbindcon}[2]{\ti{unbindcon}\ \db{#1}\ #2} % % \newcommand{\bindnone}{\ab{[], []}} % \newcommand{\bindvar}[2]{\ab{[\,#1 \mapsto #2\,], []}} % \newcommand{\bindcon}[2]{\ab{[], [\,#1 \mapsto #2\,]}} % \newcommand{\bindconlarge}[4]{ % \langle [], [\,#1 \mapsto \langle \pile{#2 \\ #3 \rangle\,] #4 \rangle}} % \newcommand{\bindmod}[2]{[\,#1 \mapsto #2\,]} % % Haskell syntax macros: math mode assumed \newcommand{\system}[2]{#1@;;@\cdots@;;@#2} \newcommand{\module}[4]{module\ #1@:@\ #2\ #3\ #4} %%% \newcommand{\exportnone}{\,} %%% \newcommand{\export}[1]{@export@\ #1@;@} %%% \newcommand{\importnone}{\,} %%% \newcommand{\importcomb}[2]{#1\ #2} %%% \newcommand{\import}[1]{@import@\ #1@;@} %%% \newcommand{\importwith}[2]{@import@\ #1\ #2@;@} %%% \newcommand{\rename}[2]{#1@<-@#2} %%% \newcommand{\declcomb}[2]{#1\ @;;@\ #2} \newcommand{\exposing}[1]{@expose@\ #1} \newcommand{\hiding}[1]{@hide@\ #1} \newcommand{\importnone}{\;} \newcommand{\importcomb}[2]{#1\ @;;@\ #2} \newcommand{\import}[2]{@import@\ #1\ #2} \newcommand{\rename}[2]{#1\ @=@\ #2} \newcommand{\declcomb}[2]{#1\ @;;@\ #2} \newcommand{\type}[2]{@type@\ #1\ @=@\;#2} \newcommand{\data}[2]{@data@\ #1\ @=@\;#2} \newcommand{\tuple}[2]{@tuple@\ #1\ @=@\;#2} %%% NEW! \newcommand{\view}[3]{@view@\ #1\ @=@\;#2\ @where@\ @{@\ #3\ @}@} \newcommand{\class}[2]{@class@\ #1\ @where@\ @{@\ #2\ @}@} \newcommand{\instance}[2]{@instance@\ #1\ @where@\ @{@\ #2\ @}@} \newcommand{\signature}[2]{#1\ @::@\ #2} \newcommand{\binding}[2]{#1\ @=@\ #2} \newcommand{\lamexpr}[2]{@\@ #1 @->@ #2} % While lambda defs. change... if change, take care of preceding line MMG \newcommand{\lamb}{@\ @} \newcommand{\whereexpr}[2]{#1\ @where@\ @{@\ #2\ @}@} \newcommand{\compexpr}[2]{@[@#1\ @|@\ #2@]@} \newcommand{\genclause}[2]{#1\ @<-@\ #2} \newcommand{\qualcomb}[2]{#1\ @,@\ #2} \newcommand{\genguard}[1]{\ #1\ } \newcommand{\caseexpr}[2]{@case@\ #1\ @of@\ @{@\ #2\ @}@} \newcommand{\simplecaseexpr}[5]{@case@\ #1\ @of@\ @{@\ #2\ @->@\ #3;\ #4\ @->@\ #5\ @}@} \newcommand{\iteexpr}[3]{@if@\ #1\ @then@\ #2\ @else@\ #3} \newcommand{\itexpr}[2]{@if@\ #1\ @then@\ #2} \newcommand{\gpat}[2]{#1\ @|@\ #2} \newcommand{\aspat}[2]{#1 @ @@ @ #2} \newcommand{\fclause}[2]{#1\ @=@\ #2} \newcommand{\fsym}[2]{#1\ @;@\ #2} \newcommand{\fpri}[2]{#1\ @;@\ @else@\ @;@\ #2} \newcommand{\aclause}[2]{#1\ @->@\ #2} \newcommand{\saclause}[4]{#1\ @->@\ #2;\ #3\ @->@\ #4} \newcommand{\asym}[2]{#1\ @;@\ #2} \newcommand{\apri}[2]{#1\ @;@\ @else@\ @;@\ #2} \newcommand{\dotted}[3]{#1\ #2\ \ldots\ #3} \newcommand{\functype}[2]{#1\ @->@\ #2} \newcommand{\predtype}[2]{#1\ @=>@ #2} \newcommand{\xp}{\dotted{x}{p_1}{p_n}} \newcommand{\xpg}{\dotted{x}{p_1}{p_n\ @{@\ g\ @}@}} \newcommand{\es}{e_1\ \ldots\ e_n} \newcommand{\ps}{p_1\ \ldots\ p_n} \newcommand{\vs}{v_1\ \ldots\ v_n} %%% NEW \newcommand{\xs}{x_1\ \ldots\ x_n} %%% NEW \newcommand{\cT}{\dotted{c}{T_1}{T_n}} \newcommand{\cTm}{\dotted{c_i}{T_{i1}}{T_{in_i}}\, @|@\range{i=1}{m}} % syntax meta-language \newcommand{\arity}[1]{\tr{arity}\ #1} \newcommand{\infix}[1]{\tr{infix}\ #1} \newcommand{\prefix}[1]{\tr{prefix}\ #1} % \newcommand{\tl}[1]{{\sc #1}} %OLD: \newcommand{\Haskell}{{\sc Haskell}} \newcommand{\Haskell}{Haskell} %\newcommand{\subsubsubsection}[1]{\par\noindent{\it #1}} \newcommand{\subsubsubsection}{\subsubsection*} \sloppy % a few hyphenation patterns, anyone? \hyphenation{da-ta-type da-ta-types} \hyphenation{Has-kell} \begin{document} % Set the float fractions to sensible values \setcounter{topnumber}{2} \setcounter{bottomnumber}{0} \setcounter{totalnumber}{2} \setcounter{dbltopnumber}{2} \renewcommand{\textfraction}{0.1} \renewcommand{\floatpagefraction}{0.9} \renewcommand{\dblfloatpagefraction}{0.9} \setcounter{page}{0} \begin{titlepage} \setcounter{page}{0} \outline{ \vspace{.3in} \begin{center} {\LARGE\bf Standard Libraries} \\[.1in] {\Large\bf for the} \\[.1in] {\huge\bf Haskell 98} \\[.3in] {\LARGE\bf Programming Language} \\[.3in] {\large\bf Revised: Sept 2002} \end{center} \vspace{.15in} \begin{center} \large \begin{tabular}{l@@{\hspace{5mm}}l} Simon Peyton Jones$^8$ [editor] & Lennart Augustsson$^9$ \\ Dave Barton$^7$ & Brian Boutel$^4$ \\ Warren Burton$^5$ & Joseph Fasel$^6$ \\ Kevin Hammond$^2$ & Ralf Hinze$^{12}$ \\ Paul Hudak$^1$ & John Hughes$^3$ \\ Thomas Johnsson$^3$ & Mark Jones$^{14}$ \\ John Launchbury$^{14}$ & Erik Meijer$^{10}$ \\ John Peterson$^1$ & Alastair Reid$^{15}$ \\ Colin Runciman$^{13}$ & Philip Wadler$^{11}$ \end{tabular} \end{center} \vspace{.15in} \begin{quotation} \noindent Authors' affiliations: (1)~Yale University (2)~University of St.~Andrews (3)~Chalmers University of Technology (4)~Victoria University of Wellington (5)~Simon Fraser University (6)~Los Alamos National Laboratory (7)~Intermetrics (8)~Microsoft Research, Cambridge (9)~Sandburst Corporation (10)~Microsoft Corporation (11)~Avaya Labs (12)~University of Bonn (13)~York University (14)~Oregon Graduate Institute (15)~University of Utah \end{quotation} \vspace{.2in} \begin{center} Copyright (c) Simon Peyton Jones. \end{center} {\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 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 a definition of the language Haskell 98.} } \end{titlepage} \tableofcontents \startnewstuff \sloppy \setlength{\parskip}{0.25cm} \setlength{\parsep}{0.25cm} \setlength{\topsep}{0cm} \setlength{\parindent}{0cm} \renewcommand{\textfraction}{0.2} \renewcommand{\floatpagefraction}{0.7} % \parskip=6pt plus2pt minus2pt %\markboth{\rm \thepage\hfil \sl \leftmark}{{\sl \rightmark}\hfil \rm\thepage} \pagestyle{headings} \startnewstuff \pagenumbering{arabic} \input{introduction}\startnewsection \input{ratio}\startnewsection \input{complex}\startnewsection \input{numeric}\startnewsection \input{ix}\startnewsection \input{array}\startnewsection \input{list}\startnewsection \input{maybe}\startnewsection \input{char}\startnewsection \input{monad}\startnewsection \input{io}\startnewsection \input{directory}\startnewsection \input{system}\startnewsection \input{time}\startnewsection \input{locale}\startnewsection \input{cputime}\startnewsection \input{random}\startnewsection % \input{bit}\startnewsection % \input{nat}\startnewsection % \input{signed}\startnewsection %\input{interrupt}\startnewsection % There's no extra indexing stuff yet. % \startnewstuff % insert the extra indexing things LAST % \input{index-extra} % There's currently no bibliography! -- jcp % Add a contents line for the References -- may be off by one page %\addcontentsline{toc}{section}{References} % \bibliographystyle{plain} % \bibliography{library} % \startnewstuff \printindex \end{document} % Local Variables: % mode: latex % End: haskell98-report-20080907/libraries/maybe.verb0000644000175000017500000000144411345221573020375 0ustar marcotmarcot%**The Haskell 98 Library Report: Maybe Utilities %**~header \section{Maybe Utilities} \outline{ \inputHS{headers/Maybe} } The type constructor @Maybe@ is defined in @Prelude@ as \bprog @ data Maybe a = Nothing | Just a @ \eprog The purpose of the @Maybe@ type is to provide a method of dealing with illegal or optional values without terminating the program, as would happen if @error@ were used, and without using @IOError@ from the @IO@ monad, which would cause the expression to become monadic. A correct result is encapsulated by wrapping it in @Just@; an incorrect result is returned as @Nothing@. Other operations on @Maybe@ are provided as part of the monadic classes in the Prelude. \clearpage \subsection{Library {\tt Maybe}} \label {Maybe} \inputHS{code/Maybe} %**~footer haskell98-report-20080907/libraries/monad.verb0000644000175000017500000001126311345221573020376 0ustar marcotmarcot%**The Haskell 98 Library Report: Monad Utilities %**~header \section{Monad Utilities} \label{Monad} \outline{ \inputHS{headers/Monad} } The @Monad@ library defines the @MonadPlus@ class, and provides some useful operations on monads. \subsection{Naming conventions} The functions in this library use the following naming conventions: \begin{itemize} \item A postfix ``@M@'' always stands for a function in the Kleisli category: @m@ is added to function results (modulo currying) and nowhere else. So, for example, \bprog @ filter :: (a -> Bool) -> [a] -> [a] filterM :: Monad m => (a -> m Bool) -> [a] -> m [a] @ \eprog \item A postfix ``@_@'' changes the result type from @(m a)@ to @(m ())@. Thus (in the @Prelude@): \bprog @ sequence :: Monad m => [m a] -> m [a] sequence_ :: Monad m => [m a] -> m () @ \eprog \item A prefix ``@m@'' generalises an existing function to a monadic form. Thus, for example: \bprog @ sum :: Num a => [a] -> a msum :: MonadPlus m => [m a] -> m a @ \eprog \end{itemize} \subsection{Class @MonadPlus@} The @MonadPlus@ class is defined as follows: \bprog @ class Monad m => MonadPlus m where mzero :: m a mplus :: m a -> m a -> m a @ \eprog The class methods @mzero@ and @mplus@ are the zero and plus of the monad. Lists and the @Maybe@ type are instances of @MonadPlus@, thus: \bprog @ instance MonadPlus Maybe where mzero = Nothing Nothing `mplus` ys = ys xs `mplus` ys = xs instance MonadPlus [] where mzero = [] mplus = (++) @ \eprog \subsection{Functions} The @join@ function is the conventional monad join operator. It is used to remove one level of monadic structure, projecting its bound argument into the outer level. % There is no convincing small-scale example for mapAndUnzipM The @mapAndUnzipM@ function maps its first argument over a list, returning the result as a pair of lists. This function is mainly used with complicated data structures or a state-transforming monad. The @zipWithM@ function generalises @zipWith@ to arbitrary monads. For instance the following function displays a file, prefixing each line with its line number, \bprog @ listFile :: String -> IO () listFile nm = do cts <- readFile nm zipWithM_ (\i line -> do putStr (show i); putStr ": "; putStrLn line) [1..] (lines cts) @ \eprog The @foldM@ function is analogous to @foldl@, except that its result is encapsulated in a monad. Note that @foldM@ works from left-to-right over the list arguments. This could be an issue where @(>>)@ and the ``folded function'' are not commutative. \bprog @ foldM f a1 [x1, x2, ..., xm ] == do a2 <- f a1 x1 a3 <- f a2 x2 ... f am xm @ \eprog If right-to-left evaluation is required, the input list should be reversed. % Omitted for now. These functions are very useful in parsing libraries % - but in a slightly modified form: % o It is conventional to return the _longest_ parse first - not % shortest first. % o The function is too strict - you can't get any part of the result % until the entire parse completes. The fix is to use the function % force when defining zeroOrMore. % % force :: Parser a -> Parser a % force (P m) = P (\i -> let x = p i in % (fst (head x), snd (head x)) : tail x) % % but how are we to generalise this to an arbitrary monad? % % The @zeroOrMore@ function performs an action repeatedly - returning % the list of all results obtained. The @oneOrMore@ function is similar % but the action must succeed at least once. That is, % \bprog % % zeroOrMore m = zero ++ % [ [a0] | a0 <- m ] ++ % [ [a0,a1] | a0 <- m, a1 <- m ] ++ % [ [a0,a1,a2] | a0 <- m, a1 <- m, a2 <- m ] ++ % ... % % oneOrMore m = [ [a0] | a0 <- m ] ++ % [ [a0,a1] | a0 <- m, a1 <- m ] ++ % [ [a0,a1,a2] | a0 <- m, a1 <- m, a2 <- m ] ++ % ... % % \eprog The @when@ and @unless@ functions provide conditional execution of monadic expressions. For example, \bprog @ when debug (putStr "Debugging\n") @ \eprog will output the string @"Debugging\n"@ if the Boolean value @debug@ is @True@, and otherwise do nothing. The monadic lifting operators promote a function to a monad. The function arguments are scanned left to right. For example, \bprog @ liftM2 (+) [0,1] [0,2] = [0,2,1,3] liftM2 (+) (Just 1) Nothing = Nothing @ \eprog In many situations, the @liftM@ operations can be replaced by uses of @ap@, which promotes function application. \bprog @ return f `ap` x1 `ap` ... `ap` xn @ \eprog is equivalent to \bprog @ liftMn f x1 x2 ... xn @ \eprog \clearpage \subsection{Library {\tt Monad}} \inputHS{code/Monad} %**~footer haskell98-report-20080907/libraries/h98-libs.gif0000644000175000017500000005447711345221572020463 0ustar marcotmarcotGIF89a²r÷C;-E=/C=2F>2D=3E@5FB8HA3GB7ID9KH?ZQAZRD\SF^SD_VH_XI`VEcZFaYKm^Gk^Ic^Pd]Pk`NmcSxfIqdPqfTqhVukTqjZtk[vmZum]ykS}mS}nVymXzn\vp_{p^wsexq`ytesave‚s[€r\…y_‰z_€u`‚xf†{fƒ{k„}h…}k}eˆ€l‚k‡‚r‰ƒr„p•ƒg‘i‘ƒm’…i˜‡mˆfœŒi‘…o”‰v“‹u™‰q˜t˜y—~žqœ‘zœ’ž•|¢‰b£‘u¤p¥“t¢“{£–|¦•z¥•}¨•t¬—u©šy¯›{­™|±z´ž{º§|€€€ —€¢˜¦™‚¦œˆª‚¬›‚¬ž‚«Ÿ‰¬žˆ°ž«¢‰¬¡‰®¦‘³£€¶¡‚°¤Š³¥‰²¨Œ¹¤€¼¥€¹¦ˆ½«‡¸¨¾©ˆ½«Ž°¥³¨·­’µ¯š¹¬’½­¾²—¸°š¿±™¾´™Â¨Áª„ïÀ¯“ų϶„ȱŠÌ²ŠÏ·Ä±“Ų•Å´–Á´˜Æ¶—ƹɵ•Ͷ“Ë·˜Î»“μ•ʺžÊ¼ŸÍ¹›ÍºœÌ½›Ð·ŽÓ½Û¹…й’Ö½”ѼšÑ½Õ½˜Â¹¢Ç¼ È¹ É¾¡Í½¢×À—՘ݗÜÃÝÉžÍÀ£ÏĦÈÀªÑÂ¤ÒÆ§Ó¿ ÕÄ¡ÖŤÒÅ«×Ì­ÛÆ¦ÝÆ ÝȦÙÊ«ØÈ­ÚÍ®Þ̪ÜÍ®ÔʱÙ˱ßЬØÐ·ßÓ³ÜÒ·àÂ’äÆ˜ãÉçÊëΖâʦäÏ£áÌ«âέéϧàϳåÓ¯ìÒ¦ïÖ êÕ©íÕ¯àаàÒ·áÕ´åÓ³æ×²çÖ¹ãÙ¾æÚ¹èÒ°é×±ìÖµèÖ¸éÚ¹éܺëÜ¿îÝ»ïܾòÜ­óàºñã½ôä½çÞÄîßÂëàÄõãÄöæÀôçÄöçÉ÷éÅóèËõìÐùîÐúó×ÿÿÿ!ùú,²r@ÿõ H° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ£Ç CŠI²¤É“(Sª\ɲ¥Ë—0cÊœI³&B8sêÜɳ§ÏŸ@ƒ J´¨Ñ£H“*]Ê´©Ó§P£JJµªÕ«Om¢ ]8tÒ®‹m]Ù±cÑ©]+®mÛzpãÆ]§n­ZhÐÔ¾{g>²Ø° GØ™agá&L8^q½xõêÅ­reÊm¡‰Ó¼¹«ZiŒA‡ý :œ:ÎåÚ–[Z\9têV«­§N]4»ë`×½}7¯Úua½‚KÖ,Ú´}ݾ•+—n_¼zùÚýk6ðà‡3VÜøqäÉ–/sÿ˼9³g°¡ÃFoµjÖªaËFGÛ6nÝèx£ƒþ;8iâÆ…V_è('sÍÕe{õE]`‚m—wÜ…ã˜fßQfåqÍy¥©§hì¦Ú{«ÅÛkôÕ¦:¹Õ–ßZüÁèßpÒfÜqɈà\ Ò¸–tkáó u*¦d…ŽAö]xÜ€W^‡~VhhÅÇUgV5Õ€a`#~¥gµÉ$lje¶Ì2›Í3ÏiôÕÃ&ZeJs6ñô‰˜l¢3O«±3O[“¹ÍkÁyÖ£ê©E˜4x–&k™Ûy Ö•ækrÚ¹V9]z‰ ˜bŽYf敦§v)ÿè&œÐÈI'\wŽ•çž}Æóg5êZ9†"Ú‹¢Œvå裢Iª^¥¦Éˆi 0‚•©ZžÖê<¢ªEj—}f8cb³ê™®^º¦¬›½çœyáZž£éIV¯¿K(±‡:‰ìpÖâX¯³”~íš}ip ÙÆ&(·v}{\¸§ŽVî¹­Šs)µl* gœµÅ‹-Œº^YV`~þ9ò „²SìdÇn&›£‹& b䬳–@‘4ú«ne+¬«vECØ@‘B˜2ÊèyªY¤ÅÆ©Õl*Íi§Asšž©³Ž¨å¬¨Ñ¦ÙíÙo^ãuÈgk¬V3Íü$ƒ:o.³ušJ‡ÿtoÆM´Ñ¬Ê½VßäÜà“ æ†µ44øƒ½`VWùp\ãõuWáÄ`”ž¤]ÛÚs`aXó6/¼Ô–÷Þ.þÜ—@…ž¶nG®– >åÐ'aæþtµ4QSžu`—‡•¹×röØÞš¶rjg*NÛos4:t×fêµ±îú›°«Ã{O5=4Ú„t8äóŽß„ý¼ãc]6ÄK½ÎñÈKËÖ4÷¶*M 6c±Ójb#8åàLgäYDЫùÅ*Hiº[Ü"§~±¬®ˆF4ø”_ ¯,`âŸ4,”9'8kÙš'ž@¡$à žxŒ·Z“(q<£ JÿÈðŒÂµE7?¡à– '%¾–nΈÈýÄm‡ÕB¾#>¡Aaã'^ËÀ LâQvÙÚ:~–I$`'GèÅÅ !4@(XB,ÌfDqüD30*ŸQ0¢o]µQN d\¡ á^érõ Ê¦ðŠG‘¥rc¥•Üœã( 9mǪ̀Üò@æL‚¡`¯öã5¿à£@‘aʦŽBòˆs >ä”ÿ«HÁj¥rT2{heø -ÔÒ'$ü$nP….´(¨B•MNå8”œ’2‚C²³.F  ]S{¶Á'¨Ç>çóñÄJ†4šaJJ£„qE(~ˆ^S€ÊXÞ)'70Eí°çàÔQCÆã£‹ô‰íèiO9¹EPõä–|¢oÞì'qK`nZ€Ÿô4G@)@6 AtH'Drª¯†*(pÕ'³Äè<€¢-.µ¾äI Þ Ï øäUµêPмá'(‚A f1K…8ÕéNÚÓŸ–ì,"ºËWÜšŸ¡£Wå4':€èŒÖH{YÇ;á‚{ÿàŽž°‰‹¾ÔÑŽ¤Îc5tŠ%Ô„¹Ú´(}Ðß2~2„K¥e •Öq¨S±U×N¬ô€Oš»– ±uס€‘Š®†âmS_rS-×–w@qúà8ÀApðƒˆA,9ôAïG`wRòl (¸à¦Yà´‰>™CÐ(õ™ŸaÁpù£T‹¦ŽŸÈAÂ÷‘|{âƒwЕÛÅ{›ÞbÔeåð­°³µ‘IðÉ Ô§©­c7ÆOeDá»ô´ÿ°RKj#¸Ú†´–¡Ouk<êç+#Ń:²µ§Ëîqy:±rR ʘp¬£1"œPÒ7®©CY(kO „RÀ >ÉÆG„ EdhE]le—Ÿø Tcipïø,[|ÄGõOVÐ-&V/Kl3 ³ø¤¤ÆÞV°ß¬ÃÐvÅd²ðÊŸ„£ÆV¥Ö—gpÔA¹¶‚<3TXƒó´y~G ’{®X'9€¡W¸Ê›'„W'Àƒ«˜ Ÿdf¿¶X$Mó„O5\ÀÍ“l°ÚÈå6w°w’ƒpàËÏÔÁEtí“ôÚžnåË2û‘¥OÿX(¦\¥1®,/h‰¶´a6™=‡Cà+ê 4æ¼³:3µ‘m(ÑèZg>Äb±VShBßã¶î>òágD¾‘ä¨`<â×§eˆ5åˆÆj%ÂÛìåêVï=Ö¾õu¶µÂ0’×Uç4/ ÇÆVSø‚åÙ)W‰ž¶¹žáÒžóž©óùõiAí8lðsœ'ªœýùŸá 03 ®Q Ÿ0"âhÙ© ûÁ =”º:-îT¡#ã€Ì“&ÊBP: é⡚¢‡HŸ"D—Ãé,(ÚŸ*ŠœãМ„ÑXÿÆï¡œq¤Ö2)Yš\‚'h!”NÊ‘[×…×U]…$›Ceqr… ýI†á æà²‹`§9—Æ,82"£A@ªC$3vg™’~Gähh:jŠg±AGxc§Öõ~ÔR§V¢+º¨§*Ú§ jƒ:,cÇlˆ )Ì‚£óâô¨pÄuA·'p–ª+i k›Ú&Wå©Õ•@¡:§kAªÃaªyº§ªÊ€ª!®:ˆ„ʆjY‰Z«Œ:-Žš@»©·L~çǬ™ZmÖ¦È ª»Ê¬ª×õh§ªŸ|ê§Ô ¨PB…°«É­Ã1"©Ušÿgš”9BQ:ZœLg¶’-;äys„sEX3Ä6µ*aQ Xóµ±5ÑÆ tÔ)‚Ó¤Mš&^ó&Jø‘KLyà lQ@J¨±y£„F* ,+EÔ°ámÁɰ“7}±j6€óa¬°q±–•±t¡{S«" m$Û¤º¡(픲pò{ˆ7†z=o"³á25K7» 9»³AÒ³o—°A;£kvD»ƒÒ‚´,¢´&ò°M¬&;µ!«#[²ý¥µuÁµ\ãµ.¶1;³f» 6ëµk[Hm«+oû³e×7r›µt‹ê¢ ˜´¢m‹±Çµ›B8²{cµÿW‹AÞ™¸&û6(š`ŽÎÊ&ÚB=j’äqºÍ”P?A câ±üPpälзÜT¯Ï¢mÞB·ý’1ƒs]Ó²J¨½FX?A½ð*ogˆ)Ù‡rcžL9%vÑ(Ð;åR VÄ05€;Vµú,ÍÔð° §á åK0%“?8÷ &×_Ð5ÒF¾Ò¢»kU=:;E'û¹§.áäò?ø+V*)ü ½h!½âI'èÐ&i œ‘½º¡‡x'øá^uñ²jK㫲2òÁ9l#Ó»îƒALy®Í*B½ É <–t¼*PÀó?ÿc&Ò´/÷¾ð9Ð\ ]>¡ö¾>!©Ñ ÷ÖI¾ÀÆ bÄŸ3‡ÖR’s¼ÕPS÷¥ úè+•#³ 6ÿë»@¯A‚ð-Àmr4–)…ìøÔŒ4wì™ǵDÇDÓgô(ñS°Ã6r ðNåÐÇK¡ ‰u œÌ*Lõ›à,ÕXFlPð 5úøBžE)¤\ÊhT ñBª¼Ê3üy­Æ—i¼Æm%|ve,¡ø$¶ÿ½w=Ø ü­ äó"äkGäFNHnsJn'ŒÚä>©¾&%IåZ)ªq‡èÓru2Èåîaþâ.#ã•æˆ´ø m9îE;®«õÐâsî^$ã,8YäF^ê{¨n¡Ï‘ kÕ5aëÀì®W¬3ýt"ÇŽ6‡§i—€fYzRwëW8žæ˜ˆrÅvdiœ)8 ˆ-¬6¤2Ò/ê,ƒ{ÿå%|qáÃ~¡íI2Þ~6àÎ ânh‘hîŒ1‚з ØîU÷‚˜‚ñN‚ó~zõnîny¡ú>'ÞïÁ«&ÿw¿~?ŽEªÜ¾ðâÐðOîùL/}ß§ƒçÒñj©€ O–"o‘$ð&Ïï«–òž²òc$.oð1¯¬3Ï05Ï:IO§î¯îY·€•Xuð‰HÛò]È#ˆíi<®²Å#ôåz‘TUq¡|-Nï ù›Ñ‡…̤Õ¨aXœû…’·ƒWVgq)4‚´TK«6¸r4&[÷ *ë>„»­ùdž¤÷´Õ+}òŸˆ I‚ÿD4ü|øC’ø XxŸæ¯”’?=-Wù.o„ÛCxÇ‘¬¾×ùÌ›"úyoO{oúùà÷m§úXyCRøzfZ±ßVŠ/uŒÿV¶ŸgB#º¯&Ù£[˜ß_ ÿ©œ_'ž©çg®˜ü´ü}rúmÇuªH¬?ýÓ/ýÕ(¢ݺuïâćÝÁw袽3ø.\¸x¡]T@ÌFŽõ}RäH’%MžD™’dG–-]¾„SæLš5mÞÄ™SçNž=}þTèP¢EEš”¦J¦M>…UêTªU­^ÅšUëV®]½~VìX²eÍžE›VíZ¶mݾ…Wî\ºÿuíÞÅ›Wï^¾}ýþXð`Â… FœXñbÆ?†YòYÔ©#8 AlÒ^'î4q—Ñ]¼ÚÄxᢽŽVNöCˆ°MOœè¶À‰äȽÆü5êÐâP?®P´‹â¤…útiÕ¥¡“Í­W¯Ðå ),§ÝeyõÖM¯0šBˆ Á‹s¯yºÐ—/gÞÌÙó:ТI›>N5Ö\ƒM¶rh{Ç6ñ‚Ó 8tzû-šàp®¹ÐÃP9æH{.:l¦ûкë²Û®»ï°<óÐso=tÚs¯øÜÛŒ¾ÒìÃ/¿Î>S'´Ñn< 5)"ð5TðAÜ”PIßS€›@â.Ä0¹ñ6tD-EÄ®í¸Ç;ðRT§¼óÂIÏ!öŠqF…j¬Ç7uÜ´k~PÈÕˆ„-¶ië3½%™äͷߢœ(šãŠ«2¹Ë˜§ÿ²ÉD@ñª“/¿u°AçºñоzFU³„ÞŒÏÅÕ|±¡ƒÆ':ßps7Xq³p;]{á¦WîÀ$ L=}ÐÓç&¼ 0Ãd4½½#-¾4ש'Fu0 oN…,íô:M7ãÔÓC RK%èÔRu¯!Û{5Vlf¨Ö‰n(×]yõU`Ö½pŒ2Ùee¼ÐÙ0›“–ÆjÇÄ6½Ì:½ÔÛo7íT9rË=·Útid—=VáVYÉ¡ÕÖqp%Íß}{ÕÎß ¾ŽØ·-øÚƒ›ÕZ7ÇsØÚˆµ¥¸ÛLuÌøÓÍ=×T¢u[SMˆ\…5VCëµ·ê|›Ûwÿ»~enYØmš¨f&³¬XLש›ƒ4u/½rªGQk|󠱎ÏÔù8«zVgjÜ^Ü\!f˜ÙaÇKrãË­fLßÓ4•Kïž{ø6— ¦×Ý £ød[î6ëjûíüâVhnsí6oâôNúò9ñù{ÓÀQ<œÂ'D¼9Å{eÜñP!HrbÏ;ÝvÓÐÑœóØ?Ï}Ñc ÏÒOg[·ã[¹ÖݬûnÙס]ܾýÖ ›Ý}'¼÷à‚'mxnŠçæq“ïvùʯs^æ6—¦é‘ U¡;öJ·½µyï{áZqÜS¾ÕåÍ=´Ý@ð»DVW³—ü¬‹q ±œΆѱ!±¡Ã„ñh>Ì“1Ǻ"RçXÓÑÝSœr<‘sä.x+Šˆ€Z,Íúº»/Š/Œ!c8dè¡Fç†9ÔØ/—¢ñ8B¤£«ƒÄ)ñ<{쎻H7 r[„¼ÈÙ¥D®OS^lØ#Çx¬I¢‘†iĤÒÚ8DN¾Q!Aü¡³ˆ(Êà|h:à;åøú¨Jfò•IÛE4âÅTªCÿÿsEÙ\Λ)ÒF š`ì3y„Ê>äZ¸¢s¬è€’ùa":Ú©v^¦MŒ%Ë60ÜœŽ9“k4“"âH+A¢"‹ùJè€Sœä$Öúô׹̬³ zg¨âÉ™yN¤ž“ÔT>÷©Ïyø Â(AïhP˜3X OCãöPŒüŒu—eˆªƒÑq–Íœç” ÝÔyvº³? é$éé6”âÓ=+í§:þy΀Žg 3VMƒdœ^‹a;OO%ʹnUÔ:á*FºQFþ-NH¡*ÏQBçmhL)?÷yW­¢RŽ^=Vb¥±M–$1È aãç½³eÙŠÿ[²0ûOˆhƒ¹ Ehiñ‹_„V’ø„×! Ö⤠kIAjX9½ç2‚t¹1òq\‰dÔ¢TŸÒäµTÉã2–q`X‚Ï]-žëˆeˆ¨—©Çi#K¶QV™=ºì&5›ÎBÄ -iiá‹ÓnÆœˆ­kY+Š`¤‘†µ­Îms»Ûøt4 Ae*`8Ð"¸Änq«7ì€.€ L LØMÊ]F3ÐáêZçºvÓnEÈ–I”˜“hE+BÛ Ð„WZãÏysZô®—v’t­k9_Qà‚¶—´ï:ð»!ÔàÖº…dZž¼rU¸@$îoÿa÷CH*»V®†9l]ìÚµ¹(mh9á‹ÉF£²-f1w‘Ͷª!lRˆˆ”RK ù†j´ä/‡¬_垆·ý!]œl¤Í— †‘HnÌúFu´ýŒâÏäö­NÆ´€!ZYRÕE¦3͆ühOX UUƪ³™ç•«;ÞYF¯–1·–Úg<ý¼+•{kVQ X[VG3š±Œà$Z ‹&“£!N0çFå˜Ú;^ÐkÐ œG€{]eØù†¿$ˆ©¥j÷„€ÚçÆ´&f=£Z«è†7±Ü*cØRÂ&6nŒ8 [-t.íÏP;I¼ö¹»0ÿOetûÎÕ7Û’5îˤZr¬–|^ XscÝü´OŠpÍN]÷Ȭêp…}è\{{Ø. ¶ N”ìk-;©â›™?£m(ˆ\Û¤>÷]jk q†ä΀ ÷µªž× ²SùI“ÆM¤\Æ6ö0‡^H|6a2›äÆ)/ÄÎ HŠ'AÑ(ºIaÆ+ZÝh§+4잀>g”ûÉ̉Z&õñiq«ç•&¹‘éÜ9€†Øç, DÎæâgדúueqgìd£Ùa3í^ÓÀŒØˆµm dJ†#îs·©uÂñjâ˜Ô¶¨Éð÷МÛ„o"¨]q(w‰çÅâ•Óø¬ÿ»Çèö»¹v˽ì/‚ 9 rø];:çö§õ\úÓ§¦v·ûêô.Á¹ÍÍ@¨.ÙDb5Ë ï/üñÿñÕ"ùo½ÞºÊ‹ãòÏ?»h¾ƒh g8ˆÏëŒ+Ò>;C£‰'a£»º“)¼;¦±’º ¬:n2 À¾A°z4cP©5Üz?@·;€-Rh„K8„-@·ì‹»nñˆ7j3aˆ4„5'˜™97Ø£@@·ð… ùñ Ä4ð„t…׸ 6ÏófÀ†ØË´eH†qR†¸r£i$iÀj‹/²Ù87&0 Ùÿ j»€~ N0jc„Þ›µ=¢4tÀ‡Œ,@¾rÁh!ÁËè=R†s³€ F@ÃŒ 6[ ¶ q¸…=„BLSpÀCg;·[ØDÓÀÂ^S–!“ÐðB D€V0AÍÄù0·P¬ "C1t…24ÃŒ™˜U#©éžù á£rÈ@Ž0´8{fáL]”< –·Y"àüŒÌN̯XB9÷àK1ðKVyÜA½ÜÉJ„¤›Zë§«’ :@·VÀøã¸1jtchZWpxã/ðNuà„îT¤Í˜„3ÈE ô…„¼ŒÑ¬ P•wÀ5ÔRQ“ƒy vÀj«eZ`CϨ††;)‚ÿ8²Yã!³+u(§¾‰Ï^ó„9·4p6 šnì57ꛇQv„C¬Q–ºQ¦ŠN…JQ«úšsuè075„sëCÓ8·2ÀÓŒr_€7˜Z¸Œ=µ …yUCÕº°Ì4@ŸŠÈ…05:`œÄluP„2ø€P †75%9¥Ó:­;¯ÊÓ£ÚËB»º Ä…1ÑŒzV|¨‡\k4Árªv’ —<·Vè(þÀŒ#=të`”†H87IȘj˜ˆ=@7\Ø ¤6{¥yjƒƒRÙKj B‡ íµ_¨ÖwȆscn_0XðÃpý§IÍ48×ñÿX‡òÌ4$p‹vå¸åÒTŒS¥6 h…¨ÒLÀu€Q‚@BjS_è…€çì5Ÿà§$87\PþX¸íµ9ø¥ƒ Y“=Ù)Ry­ ùMYQCcˆ†ÈwH—xDÍÅR¹«vݦ ÉÒJÍ)Ú^›Ïs=÷èÚL“"ûŽ—…·H»^ãÛ ÒƒÑTB›•s“ø –zàYQ+Ìÿ•Y͆á… Ýyˆžµ°V¼¶9VüOI+¹W» %èÆ#8|ŠÙ…ÂÐ GzR9ÞxhÜàN£ÍÒÅX¶ÀúÌ´ð…ˆ·í嬕¾±Ú*ãøA ”Ú5Ž?Þ(v)î*¶âCöÀïPd.nä>–¨ csŠt$L–YA\ã{Øa7þáÑ e:®ãR~Úx“ ª­B˜&Ž¥3 dXŽåpðâ‹EŠá Ü ùØ\bžYi%ç5f©·|`vjœr°{¸h›n–¾|€ˆ|p߃ ÷E´hsÓ«Zz¾i n†•tHz ‡qfrÖºãÒž\Rއ",úÿ83sÑVó8¸gAÔtN—Îáufœv~çyˆçy®çhÃçwÐg™îçxøçDèZZ!íì…n臎hAœèi®h0ºèøÈh ù!޾›^“éq.i:ixNiwfJ–– —¶gˆˆé™æçé»é€Ž6+N&žæ.ŸVèq`h‡†hÈ”è ¢h7Ú$ŒÎQ¦6 l}jöj«žêü@gbæ:–fg­6쮦篖ˆÖçvîg‡èœv•ÌJɵöir¨š jÈ$fºçÂ8´©žÕ™qˆçW;?‘i©Áä×þgrpèvßž#À³hÁü“­"@z`×®\ñ¢ÿÁ,÷LÛd!¯ßAÑ<̼òÁ?¦Y‘Ó’EÎÖIí4[íUimÛn›ŽÙ–ìÚž¾Êíî©Ñm#F›þmàë%îÌ(îàÚ1 êkhn”|î)ã:ö¡ê±îô¥ìÖmt<ïïöçðžmóÆdÜŽ¶ôŽõömàtocˆøžùXû°oÁïqÑoçÆ.ÿ–î3!í?íÆYÆí~³Wp›Ží'ÜÌ §p woáîÐ& 8¦f8g¼Y±»˜iîvy ˆ íw ‡h»ípè9‰ðn}í3æîõÁÜ×¾ÜbK´³˜Fb*¦:'†mµÎñ1óN¬4áðI²!/ò‰9r^Hò^Yröhr(gˆ(wm† òˆô×¾ULÖò7ãòB§>Àð÷óêÆ=ó“óÜ5·‘6'L³‚ó? "ߌ™µ©æ@rÆó5?;'ïs)ô*taîC×KÀTô„~0ÿm²óÌ’tü†¤J#¤¥¥7¯ 8ïô9wCâu%7uyr?·m°ž>+'ôY¯ˆ×röfLftc»ç¬ÿò ·¥O—å –c„hçñßoß(ï~&›€ôQn ÷PÚ¹íS·m ¡;ûX(Ó—Ö¡Ra¨™;ø»ÑÖ¼Ž¿;*Á.÷sBwP¦V|X÷'7ww_xí¼mÓ7+'â…ȧ}_ÉÊÝóéøcøSƒ—îº1aGúè†GƇwÖ9I—‰/ŽŠ¿«ÍQ÷|`÷wíwðøðy†y{gf}?yhâw•GEw€÷'˜/øˆšù„·yöÅùÓÐùÿt½*Šßj‹çÜŒgúð~vrXðî÷Š(¶€Fè|§VßÔ›?åòN£eÑÅx,Òn¤‹.Ž„ÿ®çy/ˆ^a*—ûÚîøgÏWj…ˆ –VÈÙ Q+G´*vï0TÑoWÄœŸ[Aq¼ïž˜¦ßâ© J|Ï%æ‚xmXq{+Ÿü*ÿýËWð̯\Îcùüõ@4*}õ0}ÛAý@U&Ö·N×Ïûi7ÍÜ^ÚÇÛ ÅßÖÜw|Þ|¤öw·ü×ÿnâ¯mãW—IþÐg~ÉwþÌë›èWý¢~G~àˆuëС‹G0\8‚  DÇp Btê ‰«8¯Æyèðá[÷.HãÆÅ#÷á;“!?ÆKɲe‚!gL¸R ÇœÃá{-ºp'… M‰.Zÿ¹rЈiêô©}R§R­jõ*Ö¬Z·r½ à+ذbÇ’-kö,Ú´jײmëö-ܸrçÒ­k÷.Þ¼z÷òíë/ÔÀ».lø0WÁŠ3nìø1äÈ’'S®lù2æÌš7sîìù3èТG“æŒø4êÔ©K³níú5ìØ²gÓ®mû6wóîíû7ðà‡/nü8òäÊ—3oîü9ôèÒ§S¯ný:öìÚ·sïîý;øðâÇ“/oþ<úôê׳oïþ=üøòçÓ¯oÿ>þüú÷óïïÿ?€ 8 x ‚ *¸ ƒ :ø „J8!… Ö@­ƒ4©£NE×Pô!:ИÿM8(†O8?ý”T9Ѽ3£‹$"„ÐQ.&„9äüt#?X‘8'i$AêHc¢8Ò„ƒ ”OF) •Ò “7½ôR‘R•£ŽDêÈSÏ:IPèÌQ9âDÄ:}øaCrè!ˆâˆ(‰F¦ˆ‹."•”Œ4þdã9þT8=þ$BB2YÑ‘•&¹$ENB‰”œVi%–Zr —`~8f™áœyAk*Ôæ› É9gݹ·!ަŸ*ê"Œ…út(˜@*ÍŽúˆ,¤-F3$¥•")¦Mvzí§W–“å–âty¥©b’i¦Biºê¥› ÉÊ'­ÙÙ!® ^ÿ³gŸ'þ¹¢³/ÆX¨ g&zìŽ=úØl¤F)-’‚5 “ˆ«@Øh˜'‘•¸Ì2't£Œ9¾Ã¨IçéÆ7ÅcJä4*©ÁZ2ù2©Åìd8=‰§áTY"4½pSqºI •)’• íМ“ù°:O ´ÅÐ`¬1£‘~üÓÇ(‹ü连ÜhÊ+?{¤8.Ss’3#dsÎ9ïl¢Ï@Gtæ™E-SÒ-ïDQ µÔQ\ñÅ›Xr‹[wì5šÌ† äØ&õhv¥i÷s‘1ODÍpãŒÐÜ=ÿŒ¸BxƒÞwDHGôwÓ‚?ínÔNMõÅÓrÜq¡Aõÿ¸¦ŽÆŠ}òï*¯,mÚC®½ø‡¤Ò €}æ: DeÍë,)g˜«¢£ÑªÖý“¢ÇΈ’²#DÒ8mn¤–½ð–ÃJtÒJ¹!”emõ2z‘-q£ó¸ˆÌ^v7ꮩs »@7=wYO{NºžàÂå=ð)D|‘Š‹Ì7”“\N}ìsß‘â7?v‹KéÒ›þnÄ?‰éÌJ`9h@nm Œ Ñ (!B„u¡ C°‡AîÍ)"$ˆËBA(%$Ø Ãñ¾©~-ôÖ óG³·mÊ6ÄuxÀz$Ї©c`¸ ÞÍ!ÕKâµ·«î)ä€!G„¢GÆBòQñ$ç3E¢Å-ÒM~+ä‘’â¦)éyÿû€4ÀT4 1DKÕ,†‘QÚs,—B¶Öª‰dPº¢3n4’M*~ôãFýºµ¶¢õMg kVóZئÁR)©£»ØXªÅ}É]EÔ¤•8±OJ$”n%FJyJ4¥’Ujbe*À.ü£ÒpxöŒ†î‰ƒWÍ߯•L¥x3Ûã%uÈñ/g'%«6\ê¿«­rýåâ0x$ïì­ÄÂX‚UvS„m'‰a£ÕДµ±§õ"ÍŠDÞKw‘0V¤~.›`bH ufU#ÿY fÿ£F¼UvÌ£"¢¢”ቿ*É“tUÕª'Á¾©nN\#›Jv³£]åj¿nÛM…LJÉt'•Ýšwiì=$ ùû™ŸÂ¾…ÐH¼¸=íNò¶3›)/4˯Òü†8¿rO9iílâÛÝ]úÓ”w·Ùî[jØŸ;N³/¼æ†{†ªñ:{|Ç‹RjþQƒ—7¾—_vìQ›ù =»T7áƒ-ƒRóhÞA ÞÑ ëñ¨­C5Fxߊ^ü ^ây]ùQ Ø9|@ÿÔß0Þ2 Þ\—1©Ëÿ)ÍÁÈÖ<´ Þ@Þɧ=Çå˜:ÿ€ß¹ $±ÝbeÍ’(Ñœ¦xà|5Võ•ˆ+H´´Tm¹`À‘TËŠŸx ÄNÛ ¶cAJ f UÁ  ŒlÔ v ö`ŽÈ.UBÃ~RÞÔjáÔ)aša59!}A᪀ò‰>B6DVu!Öà1IæÞ6–Áx¦á>Ý‘!©!áÔ•ßòa®8a¬D¡Ö1 jâD\! FÙõÏÐ|HáõŒ´IÆéä þT ºø¡E¹H­¥×e_¸(SódÐÿ]©Ä]ÆHDÿTñU•¼iD(÷xàžÈÕTÉ$& ©µÍ‘ÿä ˆDÖ|5ÏÓ¤¯Ð .¦4èb–ÁKäeÕVµ×¤Äàá,Ž1’Š:$ã2Îd=#…}ŸL£‰T#•\£ÆTš6 76 {}ãD„c`#”£‰ #/®ã„Q–; c<#Ñ£=Úοå#xíc²Å`fm¤5" 6†dÈAz#Xcb5dy=ä š£Dª E_6…‰ÂãuùÕ0U)#Ç¥Üz ?±ËÑ©"Ïücc•!©˜-†-Ú Ž0J­u’õÑÿ… ÊëLÖ+~Jèà çQI5”]5$ćdR­¹/tÞPŒ‰|œÖÕ(Ž^Þ%ˆ`Ì2ð‚Ò$Ö?ÿz`ZÍœPÉÕЖõLNV>ÊVÎIWÎ Û ¡$ÅXÊŒÐa"C|HZJÃZš[ÂY\Îå]¶×ÁÏä¥:ì%K*N®¦`e0.ƒaîebJÃb†UÆ„‰¹‚V²Ÿd.MñUfXb& jfq`gªÃg†f[† \Öšiªf˜¤&^v^f _¶¦_ŠƒlfmÞ&wæænvPon p'åQŒÎAŸeêËë´MИeöxˆÙh†&Žpuš&p9Ì8º£Â(†-ÞŸeVšÜ ´(™*vÎÒ^9ðÁYpÎ@ÉÐm)œET‰ÁÏæTmY^$åÉL‰Íã5ÌÉD°h%ÿ™… ,Ü,k±‚¦Ï,hê4hº) Œ¼Ã ”… ÜȦÄ@YÀÀZú–~vTºLå)¤…¤Á‰2Q®@Ã(Z<`fR(„b~Zä*„œE$8MÆ „¾N i„݈Y°ç™]Q6é‡rQˆ߈>[‰Ê‰5¥èF®hÓ¸(•XX˜ªÃ˜–ikÖ蜒E œ£Ž$êøèd ÞN•Lßé¦P[žÝ’¥~büœf].оqÉ—ðIEL%U² ÄÞ¸YRM¸÷” B¬ÁYs)땆ž°å@``ÝåRY‰ÔƒYXDÅЂYæ\â3`1Ä>Ç:ÌA"#sBÏåB»9ürÒ+ò–D­4XÂ$°T5TôRY3F«^ó2Ä!hÐ9WL+ƒdõ ø*è-ìÛ—Ð3=§‹‰XCžP2cÂ@3BK ÄKω ó0M+´‚ t ÅΕ2 ÊN{V<ÿ)‚Q³A°A6SC±]UÁr>6Ö Î8Ö2`¦jÝ™×úr‚–¤(âN–ÆiÅ|eZýÄP0”0æœ+ÂYxÁÍÕZ@ä¶ àýpɸEœõ¬˜ ¦G›EøÂ„Ë[,E|ÈhGÃ=ø€SjGtXà«2$C­l\D .Ü+DLJR˜ÅnƒIRü@Y Â?CC”|qа‰tÖf£CÌtp±]>…6s“@Yبþ4YPÀYXÀ' á&„Y„Ã$”% Ó-P·Zä8 3o—t”&€ t“… dÐuVÄq³Å07pÞXgÿAê¶…kËíu»Ⱦ¶‚»a†ÎPÍ ]SJh$•Cfp}÷›Œ5„VL2ß4/,ƒ¶ôÂ=Ìïê…¸ÂÐ-‰-¸\ÔÛy A43\ôÁ0Ao‡I1 wY w ¹È- P“Lù:ô¦(ÃZRøWü°”cŸ”;éSâ݆’œ¤BÜ‚YÔ€WÎC”…”.ÄùXðÀ®…I;ôãE ŽJÄ}›E›Í‘#³\)ùõ‘’ΦԅL¼˜Å› ĉ-8:\È€F„¢8øvYàÁÙ@g=§y\Õ7•jU«Wÿ±fÕº•kV/Á2D‡Ï$ËÙ‰S;O]Ú}Û¤:9#ñæÅKÅÕNiË–AS'Íg=ŸëXâbÓA/Zb×Ijœ0E@¾æ¡›·¶âÅÉ#€})–¬´¼iغØ*o¶ºèhà5±î£:hÍHà…±1PW}sþ <¸ðaÆŸ¿¤Þ'¨æ,Ñ+‹í@‹gï]¬'z4ÃAz=‰Kn®Ã¶šç¢ÛWÆ@hËhç%`²Z}lë”äu$˜°Þ2Ò KÀ×p—pñ#„ÆhÙLß~ î/Áˆÿûè'–« ÀyôÉ©¨ êJÈ!‰,²*ÄŠG@¦*ÇI‹Ê§!tœlË!ÔŠ+3ôJC/K*ë7W𑯽ÐkÛh|NŒèŸÄÚ$΄>ð…<Š<»¡lÐQR,¦Dô3¯>Î'¶‘b&Lšri‡í„)5٠󭙤ѡ±ÖÉ#«G2¼tQg˜¯áÿî•$ J 8QŽð0Ig ­tj¶•*ÐxÌnë8‰mR’Bqšªó æ0*P Œ8ïå{ñ’pl³"Kô0F¡a‰M€Í¥‡jŒÚ´å"µj‡|BO/Û÷’K‰‡Ýa‚wzc}ð}è@‡YÃïßRà_Bø ñŠÇ’@-ŸŒÉ¼—¿Ä|†4€­Âð|;ÈÜÕ^ûšïá ‰š½^`²Ÿýé~û{Í3ï±ß;;ún¡¿/x‚W>Y™/ñêlÂÆžÂ NúÖú0ï¼4óÊa‰:¾Fà`:aÜÖÊyš… Zo@ÎöÚgöh¯;êÿNMtOïŽA€þàú`tÁø€xÀ‚ChaÐ`Ñ`Р Á”‚â~Å„ø££æŒPþ¤¤""pÚÆíân ­B¬*eëà&’Dˆ³bЂ¸! Ã0îïIn-ÎxŠ"Ô0@(p‚È!ؘdâ,3ª#F{fMå0èÆio@âL@Öª!ìë<ÜéÑèK« CxÖ … º®ÑÂA +%żpÖH ǰ Ÿ$)ÒIŒ¢ ç ÃAé2î=:ou$ý‘Ÿ‹GQü@BŸ‹=ÊkãZ°EÃ鄞F5‘ çé Aÿ‘È0ÙØhÑP ‹ ™Â ‚¬X±ê°åó mÆ$hñqé¡QkÃo§mí‰qØða.}b"¹Ð…-¢QEÑIа±I¸1α…«g°É §í¨fmkñ ‘ââL ©°#@x ÄãÆ$»P„F=qò!Ö-œÄìáÊ-òòxòA’^‚$ 'èP »ã-JhV &IâpÑÇA4’Wl_j%*ëñ§mèâØšÅ¹¤ $Çb4ŠÎ¸2 ÑhØa%[Ò_2&gäXñ&mR'ã'&²öhXâ¢(Lÿì(“2™2$zH@¤R@¨Ò„©°²¾‚+,½’$çÉ$Åò Ë’%™ -Ë&e’&Û'áR.}².ƒ.2F,ŠÒVø2”ò/Ç"0Éc0ogª óó¨ÓFs+%ó1Ùç+OR3Ȳ2[RÙ2S-9'm2'*{ò'2†ò‚2Õ‚8/‚êÔ“x†'Ø^‚’î%æÐ=ß“Gž¤‡ñ”¢a.IãR5ÓAóDÃq‚Ë!äÌŒÊE”ÄáÕøÄ,²„FlÄ*i¥ Çsβ…}žÇ<Å=+äÞa=ß¡=) >Áÿb>)I’ìÓIð)š?_Â?é@4,¶ŠN ´q´!”AUÅAyh "‚BÃó0Æ3+5”CÕÓC=4Déð=/>MTðPt@î“ÒôsëlE>Éá?UsF»ƒ@¤íF£ò‡ŽDx›HQIH× ïŠt½,CS2-6´;”I™4DEôãÀBJŸT’êP]Ê!ŽX4ñÈ ­º4¿LíL`¸J‘Þ®;ãŽaz¢@¤+‘Dªñ]ÌpPj>¹c'å3yRP©UxÌð Ÿ,è÷FµìU+¥"qÅîR0šXhE-®A<ØŽ€Ôy ’¾ Ãð0•N4uƒ6ÿTíbåSùO EuTy’LJSµ²U“âUwRV¹ƒVÆVéWÉ£YTƒWÛ&¾H3X[XÇX5Yc‹YñÕË6õY/¦UA•ZOÔZK•9Qت®[Íð[·4.ÅÕ`3Œ¾Þ]™EWß‚])Â]¯^‡Bé53,KYçÌB3•ž5i¤ÕaB5U¹ƒ9±•`«vŸ­buT?îa-ë0¸“R} \B„'¶nBܤ<¤¸i¹afÑA)@®ZE#'[6[ÍŠØÂBðÎJ ×ÒmV4ÆBÓîÜï9©.€QJJ`…‡„uX§ä0Ê£4ò.h†'ˆŒÿV-Vi™ÖiËjÁBjM•`9ËjGk%Fk¶k½léRlõõ@/É⟤„Æ´mÉtÎâög›E„êb„"oƒ)iðoû.U6p–j Ê”qkpk¶k¿6l/elcsrݦrÓsÙö§8sçBnV1ýJÜD·h‘-˜öötÄopãa%[—p¡L$f¿·Iqã)ÁäöËËv–gGÌ ‹qlƒ‹!2"˜2biÉ’ÔPÖ=Jýs|UV„RP/m‡IB”qçré²;N³@áXI¸)$}áîwnCödƒ:Jâ ÃP<%)ˆçTßظ€«˜)G•ÿ¦•GЇ;â&ÃhÕ€sm5¦GÝèT@°(3Ôô"÷»8¨YŒ ‘‡X‘¹‘—‘#ù=%YT«¸’Õä’Q6“ÿ©Rþ”(æwA9dÝÿ¢:Þˆm2å”u΄T9çØ¤•ÙuÚ`™ÎdùY qÙat’{ùD™„ƒ™;0¹~5Ù˜5™=y.—YŒiÅ™ñ ôŒÙP™š©Äš›ge¹yƒfù›šÞAwY’ÊYðþö=÷X9Üùpx—bE™“™|—±,6è|¬€Eaï!UÌbJ(8—$’ò![éS„çp\ÍY ®ÐÄàO’èïB ë¥npO £6?n(Z ”Mkç-6î2´^ÅÍ=âHJ: ×X¨0NZ]Rš,WZ Zš9_šešJ#©¦ï즋Nñe§G´§É J›V¨Ç£¨µ‹VtÕf”uZµššè¥:?ƒºª;n/æ<µº…¸Ú¥G¬ V¬i:L“Ĭs:­UJ“¢­õ­Ýf¨åúbéÚLïr©‘U“œúØ$Û ¤«y;«×h¥_¢«åR¬çS¦­^ÇΠÔxð&ŠÂœOV™×ÎÃí&ÿ5¤ÓWLcϾžùN/;. VÒeÊD% F¹t[…¬þrî0za‰G—£´Ú8è-d%{دߑM䬾TŒNXtÏBéÉŸ²„,ãŠb8+º!yºí׺û=³;lÁ±»·ô»Ñ*¼úb‰Ì;=®„‹šëœ®¥Â,ë½ $¾™ÖvzS¹ñ ¿)D¿1‰¿¡T>ÿ{Q¯»¶‹‚À¹5½»¦?®§é“¬†pÚ\"œD˜z½ÎÂmç-)ä[ñÀÒÃﻹ{¿H.g»ºIµÉ•µ;4MìöÖ˜ÑJ’ïDm3JRy͸ÓwŠÞ¹¨¤„Ú*“Ü9'_”Ýÿ8ƼDŸ³ÿ8k¥I£ØÛ±mo)h<˜VA3÷]xh!yÆÉÑHëï¬lEbX(Ø®ÎVBÛX=š@^¢á˜äµÝä·ŠßUþyX^àwæ?ÎgÞÜcºkoÞáÇsçO¸ì|ÞâM_ð²„"ãëáè!#EÞ¶›¾-•žI¤ßoèßÙ=Ø\¾Ký£|ë«»v3Z•DMCTKå&ÞÞクó=K¬q*"oÊ“Y„‡Úÿ2éÐDû¾ºÁzKC½À™"Q™€ï%¡›– U·§k|–¥äbѶJš‹<„Žl“2:¶â3¯Úxÿ1Ñf°=æòçIó§·óô ¦cšôïØô Ó&ùü=•‘_¿ù 9ªÛµö)âöÕ!÷„ caoÏ÷GuãLø›^Î*ÿWÚù3Ê9<¿Ûøù‚œÀwñС‹ŸB„ïD÷]¸‰ ¾ b8†ÑÐE‹v±aà B; Mœ8tåÔ©D'®\Ëz4ë¡S§P´›êÐÕ[g!Âpë&nŠpB|6Ñ­cúèÞ7Ë©§®]½yóÔ=ÅmbCŒãÆÑ£'ò9‘…ªXP¨B| B4H±âEŒ/Æ{÷Ñã޴у8±âÅú;~ 9²ä¨É”+[¾,y±æÍœ;{þ :´èѤK›>:µêÕ¬[»~ ;¶ìÙ´kÛ>9·îݼ1ßþ <¸ðáÄ‹?Ž<¹òå¨{;ý2óéÔ«[¿Ž=»öíÜGÿ>|ãîäË›?>½úõ£Å»?¾üùôëÛ¿?¿þýüûûÿ`€H`ˆ`‚ .È`ƒ>a„NHa…^ˆa†nÈa‡~bˆù;haskell98-report-20080907/libraries/headers/0000755000175000017500000000000011345221573020030 5ustar marcotmarcothaskell98-report-20080907/libraries/headers/IO1.hs0000644000175000017500000000347711345221572020766 0ustar marcotmarcothFileSize :: Handle -> IO Integer hIsEOF :: Handle -> IO Bool isEOF :: IO Bool isEOF = hIsEOF stdin hSetBuffering :: Handle -> BufferMode -> IO () hGetBuffering :: Handle -> IO BufferMode hFlush :: Handle -> IO () hGetPosn :: Handle -> IO HandlePosn hSetPosn :: HandlePosn -> IO () hSeek :: Handle -> SeekMode -> Integer -> IO () hWaitForInput :: Handle -> Int -> IO Bool hReady :: Handle -> IO Bool hReady h = hWaitForInput h 0 hGetChar :: Handle -> IO Char hGetLine :: Handle -> IO String hLookAhead :: Handle -> IO Char hGetContents :: Handle -> IO String hPutChar :: Handle -> Char -> IO () hPutStr :: Handle -> String -> IO () hPutStrLn :: Handle -> String -> IO () hPrint :: Show a => Handle -> a -> IO () hIsOpen :: Handle -> IO Bool hIsClosed :: Handle -> IO Bool hIsReadable :: Handle -> IO Bool hIsWritable :: Handle -> IO Bool hIsSeekable :: Handle -> IO Bool isAlreadyExistsError :: IOError -> Bool isDoesNotExistError :: IOError -> Bool isAlreadyInUseError :: IOError -> Bool isFullError :: IOError -> Bool isEOFError :: IOError -> Bool isIllegalOperation :: IOError -> Bool isPermissionError :: IOError -> Bool isUserError :: IOError -> Bool ioeGetErrorString :: IOError -> String ioeGetHandle :: IOError -> Maybe Handle ioeGetFileName :: IOError -> Maybe FilePath try :: IO a -> IO (Either IOError a) bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c haskell98-report-20080907/libraries/headers/Numeric.hs0000644000175000017500000000237211345221572021771 0ustar marcotmarcotmodule Numeric(fromRat, showSigned, showIntAtBase, showInt, showOct, showHex, readSigned, readInt, readDec, readOct, readHex, floatToDigits, showEFloat, showFFloat, showGFloat, showFloat, 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 readDec :: (Integral a) => ReadS a readOct :: (Integral a) => ReadS a readHex :: (Integral a) => ReadS a showEFloat :: (RealFloat a) => Maybe Int -> a -> ShowS showFFloat :: (RealFloat a) => Maybe Int -> a -> ShowS showGFloat :: (RealFloat a) => Maybe Int -> a -> ShowS showFloat :: (RealFloat a) => a -> ShowS floatToDigits :: (RealFloat a) => Integer -> a -> ([Int], Int) readFloat :: (RealFrac a) => ReadS a lexDigits :: ReadS String haskell98-report-20080907/libraries/headers/Random.hs0000644000175000017500000000245311345221572021607 0ustar marcotmarcotmodule Random ( RandomGen(next, split, genRange), StdGen, mkStdGen, Random( random, randomR, randoms, randomRs, randomIO, randomRIO ), getStdRandom, getStdGen, setStdGen, newStdGen ) where ---------------- The RandomGen class ------------------------ class RandomGen g where genRange :: g -> (Int, Int) next :: g -> (Int, g) split :: g -> (g, g) ---------------- A standard instance of RandomGen ----------- data StdGen = ... -- Abstract instance RandomGen StdGen where ... instance Read StdGen where ... instance Show StdGen where ... mkStdGen :: Int -> StdGen ---------------- The Random class --------------------------- class Random a where randomR :: RandomGen g => (a, a) -> g -> (a, g) random :: RandomGen g => g -> (a, g) randomRs :: RandomGen g => (a, a) -> g -> [a] randoms :: RandomGen g => g -> [a] randomRIO :: (a,a) -> IO a randomIO :: IO a instance Random Int where ... instance Random Integer where ... instance Random Float where ... instance Random Double where ... instance Random Bool where ... instance Random Char where ... ---------------- The global random generator ---------------- newStdGen :: IO StdGen setStdGen :: StdGen -> IO () getStdGen :: IO StdGen getStdRandom :: (StdGen -> (a, StdGen)) -> IO a haskell98-report-20080907/libraries/headers/CPUTime.hs0000644000175000017500000000016411345221572021632 0ustar marcotmarcotmodule CPUTime ( getCPUTime, cpuTimePrecision ) where getCPUTime :: IO Integer cpuTimePrecision :: Integer haskell98-report-20080907/libraries/headers/Ratio.hs0000644000175000017500000000152011345221572021437 0ustar marcotmarcotmodule Ratio ( Ratio, Rational, (%), numerator, denominator, approxRational ) where infixl 7 % data (Integral a) => Ratio a = ... type Rational = Ratio Integer (%) :: (Integral a) => a -> a -> Ratio a numerator, denominator :: (Integral a) => Ratio a -> a approxRational :: (RealFrac a) => a -> a -> Rational instance (Integral a) => Eq (Ratio a) where ... instance (Integral a) => Ord (Ratio a) where ... instance (Integral a) => Num (Ratio a) where ... instance (Integral a) => Real (Ratio a) where ... instance (Integral a) => Fractional (Ratio a) where ... instance (Integral a) => RealFrac (Ratio a) where ... instance (Integral a) => Enum (Ratio a) where ... instance (Read a,Integral a) => Read (Ratio a) where ... instance (Integral a) => Show (Ratio a) where ... haskell98-report-20080907/libraries/headers/Monad.hs0000644000175000017500000000300211345221572021414 0ustar marcotmarcotmodule Monad ( MonadPlus(mzero, mplus), join, guard, when, unless, ap, msum, filterM, mapAndUnzipM, zipWithM, zipWithM_, foldM, liftM, liftM2, liftM3, liftM4, liftM5, -- ...and what the Prelude exports Monad((>>=), (>>), return, fail), Functor(fmap), mapM, mapM_, sequence, sequence_, (=<<), ) where class Monad m => MonadPlus m where mzero :: m a mplus :: m a -> m a -> m a join :: Monad m => m (m a) -> m a guard :: MonadPlus m => Bool -> m () when :: Monad m => Bool -> m () -> m () unless :: Monad m => Bool -> m () -> m () ap :: Monad m => m (a -> b) -> m a -> m b mapAndUnzipM :: Monad m => (a -> m (b,c)) -> [a] -> m ([b], [c]) zipWithM :: Monad m => (a -> b -> m c) -> [a] -> [b] -> m [c] zipWithM_ :: Monad m => (a -> b -> m c) -> [a] -> [b] -> m () foldM :: Monad m => (a -> b -> m a) -> a -> [b] -> m a filterM :: Monad m => (a -> m Bool) -> [a] -> m [a] msum :: MonadPlus m => [m a] -> m a liftM :: Monad m => (a -> b) -> (m a -> m b) liftM2 :: Monad m => (a -> b -> c) -> (m a -> m b -> m c) liftM3 :: Monad m => (a -> b -> c -> d) -> (m a -> m b -> m c -> m d) liftM4 :: Monad m => (a -> b -> c -> d -> e) -> (m a -> m b -> m c -> m d -> m e) liftM5 :: Monad m => (a -> b -> c -> d -> e -> f) -> (m a -> m b -> m c -> m d -> m e -> m f) haskell98-report-20080907/libraries/headers/Maybe.hs0000644000175000017500000000075311345221572021425 0ustar marcotmarcotmodule Maybe( isJust, isNothing, fromJust, fromMaybe, listToMaybe, maybeToList, catMaybes, mapMaybe, -- ...and what the Prelude exports Maybe(Nothing, Just), maybe ) where isJust, isNothing :: Maybe a -> Bool fromJust :: Maybe a -> a fromMaybe :: a -> Maybe a -> a listToMaybe :: [a] -> Maybe a maybeToList :: Maybe a -> [a] catMaybes :: [Maybe a] -> [a] mapMaybe :: (a -> Maybe b) -> [a] -> [b] haskell98-report-20080907/libraries/headers/Complex.hs0000644000175000017500000000157111345221572021776 0ustar marcotmarcotmodule Complex ( Complex((:+)), realPart, imagPart, conjugate, mkPolar, cis, polar, magnitude, phase ) where infix 6 :+ data (RealFloat a) => Complex a = !a :+ !a realPart, imagPart :: (RealFloat a) => Complex a -> a conjugate :: (RealFloat a) => Complex a -> Complex a mkPolar :: (RealFloat a) => a -> a -> Complex a cis :: (RealFloat a) => a -> Complex a polar :: (RealFloat a) => Complex a -> (a,a) magnitude, phase :: (RealFloat a) => Complex a -> a instance (RealFloat a) => Eq (Complex a) where ... instance (RealFloat a) => Read (Complex a) where ... instance (RealFloat a) => Show (Complex a) where ... instance (RealFloat a) => Num (Complex a) where ... instance (RealFloat a) => Fractional (Complex a) where ... instance (RealFloat a) => Floating (Complex a) where ... haskell98-report-20080907/libraries/headers/Directory.hs0000644000175000017500000000225511345221572022333 0ustar marcotmarcotmodule Directory ( Permissions( Permissions, readable, writable, executable, searchable ), createDirectory, removeDirectory, removeFile, renameDirectory, renameFile, getDirectoryContents, getCurrentDirectory, setCurrentDirectory, doesFileExist, doesDirectoryExist, getPermissions, setPermissions, getModificationTime ) where import Time ( ClockTime ) data Permissions = Permissions { readable, writable, executable, searchable :: Bool } instance Eq Permissions where ... instance Ord Permissions where ... instance Read Permissions where ... instance Show Permissions where ... createDirectory :: FilePath -> IO () removeDirectory :: FilePath -> IO () removeFile :: FilePath -> IO () renameDirectory :: FilePath -> FilePath -> IO () renameFile :: FilePath -> FilePath -> IO () getDirectoryContents :: FilePath -> IO [FilePath] getCurrentDirectory :: IO FilePath setCurrentDirectory :: FilePath -> IO () doesFileExist :: FilePath -> IO Bool doesDirectoryExist :: FilePath -> IO Bool getPermissions :: FilePath -> IO Permissions setPermissions :: FilePath -> Permissions -> IO () getModificationTime :: FilePath -> IO ClockTime haskell98-report-20080907/libraries/headers/Locale.hs0000644000175000017500000000072011345221572021561 0ustar marcotmarcotmodule Locale(TimeLocale(..), defaultTimeLocale) where data TimeLocale = TimeLocale { wDays :: [(String, String)], -- full and abbreviated week days months :: [(String, String)], -- full and abbreviated months amPm :: (String, String), -- AM/PM symbols dateTimeFmt, dateFmt, -- formatting strings timeFmt, time12Fmt :: String } deriving (Eq, Ord, Show) defaultTimeLocale :: TimeLocale haskell98-report-20080907/libraries/headers/List.hs0000644000175000017500000000340511345221572021300 0ustar marcotmarcotmodule List ( elemIndex, elemIndices, find, findIndex, findIndices, nub, nubBy, delete, deleteBy, (\\), deleteFirstsBy, union, unionBy, intersect, intersectBy, intersperse, transpose, partition, group, groupBy, inits, tails, isPrefixOf, isSuffixOf, mapAccumL, mapAccumR, sort, sortBy, insert, insertBy, maximumBy, minimumBy, genericLength, genericTake, genericDrop, genericSplitAt, genericIndex, genericReplicate, zip4, zip5, zip6, zip7, zipWith4, zipWith5, zipWith6, zipWith7, 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, iterate, repeat, replicate, cycle, take, drop, splitAt, takeWhile, dropWhile, span, break, lines, words, unlines, unwords, reverse, and, or, any, all, elem, notElem, lookup, sum, product, maximum, minimum, concatMap, zip, zip3, zipWith, zipWith3, unzip, unzip3 ) where infix 5 \\ elemIndex :: Eq a => a -> [a] -> Maybe Int elemIndices :: Eq a => a -> [a] -> [Int] find :: (a -> Bool) -> [a] -> Maybe a findIndex :: (a -> Bool) -> [a] -> Maybe Int findIndices :: (a -> Bool) -> [a] -> [Int] nub :: Eq a => [a] -> [a] nubBy :: (a -> a -> Bool) -> [a] -> [a] delete :: Eq a => a -> [a] -> [a] deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a] (\\) :: Eq a => [a] -> [a] -> [a] deleteFirstsBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] union :: Eq a => [a] -> [a] -> [a] unionBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] haskell98-report-20080907/libraries/headers/IO.hs0000644000175000017500000000352311345221572020675 0ustar marcotmarcotmodule IO ( Handle, HandlePosn, IOMode(ReadMode,WriteMode,AppendMode,ReadWriteMode), BufferMode(NoBuffering,LineBuffering,BlockBuffering), SeekMode(AbsoluteSeek,RelativeSeek,SeekFromEnd), stdin, stdout, stderr, openFile, hClose, hFileSize, hIsEOF, isEOF, hSetBuffering, hGetBuffering, hFlush, hGetPosn, hSetPosn, hSeek, hWaitForInput, hReady, hGetChar, hGetLine, hLookAhead, hGetContents, hPutChar, hPutStr, hPutStrLn, hPrint, hIsOpen, hIsClosed, hIsReadable, hIsWritable, hIsSeekable, isAlreadyExistsError, isDoesNotExistError, isAlreadyInUseError, isFullError, isEOFError, isIllegalOperation, isPermissionError, isUserError, ioeGetErrorString, ioeGetHandle, ioeGetFileName, try, bracket, bracket_, -- ...and what the Prelude exports IO, FilePath, IOError, ioError, userError, catch, interact, putChar, putStr, putStrLn, print, getChar, getLine, getContents, readFile, writeFile, appendFile, readIO, readLn ) where import Ix(Ix) data Handle = ... -- implementation-dependent instance Eq Handle where ... instance Show Handle where .. -- implementation-dependent data HandlePosn = ... -- implementation-dependent instance Eq HandlePosn where ... instance Show HandlePosn where --- -- implementation-dependent data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode deriving (Eq, Ord, Ix, Bounded, Enum, Read, Show) data BufferMode = NoBuffering | LineBuffering | BlockBuffering (Maybe Int) deriving (Eq, Ord, Read, Show) data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd deriving (Eq, Ord, Ix, Bounded, Enum, Read, Show) stdin, stdout, stderr :: Handle openFile :: FilePath -> IOMode -> IO Handle hClose :: Handle -> IO () haskell98-report-20080907/libraries/headers/Ix.hs0000644000175000017500000000103311345221572020740 0ustar marcotmarcotmodule Ix ( Ix(range, index, inRange, rangeSize) ) where class Ord a => Ix a where range :: (a,a) -> [a] index :: (a,a) -> a -> Int inRange :: (a,a) -> a -> Bool rangeSize :: (a,a) -> Int instance Ix Char where ... instance Ix Int where ... instance Ix Integer where ... instance (Ix a, Ix b) => Ix (a,b) where ... -- et cetera instance Ix Bool where ... instance Ix Ordering where ... haskell98-report-20080907/libraries/headers/Time.hs0000644000175000017500000000300111345221573021254 0ustar marcotmarcotmodule Time ( ClockTime, Month(January,February,March,April,May,June, July,August,September,October,November,December), Day(Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday), CalendarTime(CalendarTime, ctYear, ctMonth, ctDay, ctHour, ctMin, ctPicosec, ctWDay, ctYDay, ctTZName, ctTZ, ctIsDST), TimeDiff(TimeDiff, tdYear, tdMonth, tdDay, tdHour, tdMin, tdSec, tdPicosec), getClockTime, addToClockTime, diffClockTimes, toCalendarTime, toUTCTime, toClockTime, calendarTimeToString, formatCalendarTime ) where import Ix(Ix) data ClockTime = ... -- Implementation-dependent instance Ord ClockTime where ... instance Eq ClockTime where ... data Month = January | February | March | April | May | June | July | August | September | October | November | December deriving (Eq, Ord, Enum, Bounded, Ix, Read, Show) data Day = Sunday | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday deriving (Eq, Ord, Enum, Bounded, Ix, Read, Show) data CalendarTime = CalendarTime { ctYear :: Int, ctMonth :: Month, ctDay, ctHour, ctMin, ctSec :: Int, ctPicosec :: Integer, ctWDay :: Day, ctYDay :: Int, ctTZName :: String, ctTZ :: Int, ctIsDST :: Bool } deriving (Eq, Ord, Read, Show) data TimeDiff = TimeDiff { tdYear, tdMonth, tdDay, tdHour, tdMin, tdSec :: Int, tdPicosec :: Integer } deriving (Eq, Ord, Read, Show) haskell98-report-20080907/libraries/headers/List1.hs0000644000175000017500000000441211345221572021360 0ustar marcotmarcotintersect :: Eq a => [a] -> [a] -> [a] intersectBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] intersperse :: a -> [a] -> [a] transpose :: [[a]] -> [[a]] partition :: (a -> Bool) -> [a] -> ([a],[a]) group :: Eq a => [a] -> [[a]] groupBy :: (a -> a -> Bool) -> [a] -> [[a]] inits :: [a] -> [[a]] tails :: [a] -> [[a]] isPrefixOf :: Eq a => [a] -> [a] -> Bool isSuffixOf :: Eq a => [a] -> [a] -> Bool mapAccumL :: (a -> b -> (a, c)) -> a -> [b] -> (a, [c]) mapAccumR :: (a -> b -> (a, c)) -> a -> [b] -> (a, [c]) unfoldr :: (b -> Maybe (a,b)) -> b -> [a] sort :: Ord a => [a] -> [a] sortBy :: (a -> a -> Ordering) -> [a] -> [a] insert :: Ord a => a -> [a] -> [a] insertBy :: (a -> a -> Ordering) -> a -> [a] -> [a] maximumBy :: (a -> a -> Ordering) -> [a] -> a minimumBy :: (a -> a -> Ordering) -> [a] -> a genericLength :: Integral a => [b] -> a genericTake :: Integral a => a -> [b] -> [b] genericDrop :: Integral a => a -> [b] -> [b] genericSplitAt :: Integral a => a -> [b] -> ([b],[b]) genericIndex :: Integral a => [b] -> a -> b genericReplicate :: Integral a => a -> b -> [b] zip4 :: [a] -> [b] -> [c] -> [d] -> [(a,b,c,d)] zip5 :: [a] -> [b] -> [c] -> [d] -> [e] -> [(a,b,c,d,e)] zip6 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [(a,b,c,d,e,f)] zip7 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g] -> [(a,b,c,d,e,f,g)] zipWith4 :: (a->b->c->d->e) -> [a]->[b]->[c]->[d]->[e] zipWith5 :: (a->b->c->d->e->f) -> [a]->[b]->[c]->[d]->[e]->[f] zipWith6 :: (a->b->c->d->e->f->g) -> [a]->[b]->[c]->[d]->[e]->[f]->[g] zipWith7 :: (a->b->c->d->e->f->g->h) -> [a]->[b]->[c]->[d]->[e]->[f]->[g]->[h] unzip4 :: [(a,b,c,d)] -> ([a],[b],[c],[d]) unzip5 :: [(a,b,c,d,e)] -> ([a],[b],[c],[d],[e]) unzip6 :: [(a,b,c,d,e,f)] -> ([a],[b],[c],[d],[e],[f]) unzip7 :: [(a,b,c,d,e,f,g)] -> ([a],[b],[c],[d],[e],[f],[g]) haskell98-report-20080907/libraries/headers/Time1.hs0000644000175000017500000000072711345221573021351 0ustar marcotmarcot-- Functions on times getClockTime :: IO ClockTime addToClockTime :: TimeDiff -> ClockTime -> ClockTime diffClockTimes :: ClockTime -> ClockTime -> TimeDiff toCalendarTime :: ClockTime -> IO CalendarTime toUTCTime :: ClockTime -> CalendarTime toClockTime :: CalendarTime -> ClockTime calendarTimeToString :: CalendarTime -> String formatCalendarTime :: TimeLocale -> String -> CalendarTime -> String haskell98-report-20080907/libraries/headers/Char.hs0000644000175000017500000000125711345221572021245 0ustar marcotmarcotmodule 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 isAscii, isLatin1, isControl, isPrint, isSpace, isUpper, isLower, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum :: Char -> Bool toUpper, toLower :: Char -> Char digitToInt :: Char -> Int intToDigit :: Int -> Char ord :: Char -> Int chr :: Int -> Char lexLitChar :: ReadS String readLitChar :: ReadS Char showLitChar :: Char -> ShowS haskell98-report-20080907/libraries/headers/Array.hs0000644000175000017500000000246511345221572021450 0ustar marcotmarcotmodule Array ( module Ix, -- export all of Ix for convenience Array, array, listArray, (!), bounds, indices, elems, assocs, accumArray, (//), accum, ixmap ) where import Ix infixl 9 !, // data (Ix a) => Array a b = ... -- Abstract array :: (Ix a) => (a,a) -> [(a,b)] -> Array a b listArray :: (Ix a) => (a,a) -> [b] -> Array a b (!) :: (Ix a) => Array a b -> a -> b bounds :: (Ix a) => Array a b -> (a,a) indices :: (Ix a) => Array a b -> [a] elems :: (Ix a) => Array a b -> [b] assocs :: (Ix a) => Array a b -> [(a,b)] accumArray :: (Ix a) => (b -> c -> b) -> b -> (a,a) -> [(a,c)] -> Array a b (//) :: (Ix a) => Array a b -> [(a,b)] -> Array a b accum :: (Ix a) => (b -> c -> b) -> Array a b -> [(a,c)] -> Array a b ixmap :: (Ix a, Ix b) => (a,a) -> (a -> b) -> Array b c -> Array a c instance Functor (Array a) where ... instance (Ix a, Eq b) => Eq (Array a b) where ... instance (Ix a, Ord b) => Ord (Array a b) where ... instance (Ix a, Show a, Show b) => Show (Array a b) where ... instance (Ix a, Read a, Read b) => Read (Array a b) where ... haskell98-report-20080907/libraries/headers/System.hs0000644000175000017500000000063411345221572021652 0ustar marcotmarcotmodule System ( ExitCode(ExitSuccess,ExitFailure), getArgs, getProgName, getEnv, system, exitWith, exitFailure ) where data ExitCode = ExitSuccess | ExitFailure Int deriving (Eq, Ord, Read, Show) getArgs :: IO [String] getProgName :: IO String getEnv :: String -> IO String system :: String -> IO ExitCode exitWith :: ExitCode -> IO a exitFailure :: IO a haskell98-report-20080907/libraries/ix.verb0000644000175000017500000000745711345221573017732 0ustar marcotmarcot%**The Haskell 98 Library Report: Indexing Operations %**~header \section{Indexing Operations} \outline{ \inputHS{headers/Ix} } The @Ix@ class is used to map a contiguous subrange of values in a type onto integers. It is used primarily for array indexing (see Section~\ref{arrays}). The @Ix@ class contains the methods @range@\indextt{range}, @index@\indextt{index}, and @inRange@\indextt{inRange}. The @index@ operation maps a bounding pair, which defines the lower and upper bounds of the range, and a subscript, to an integer. The @range@ operation enumerates all subscripts; the @inRange@ operation tells whether a particular subscript lies in the range defined by a bounding pair. An implementation is entitled to assume the following laws about these operations: \bprog @ range (l,u) !! index (l,u) i == i -- when i is in range inRange (l,u) i == i `elem` range (l,u) map index (range (l,u)) == [0..rangeSize (l,u)] @ \eprog % It is the responsibility of the programmer to enforce bounds % checking for non-derived instances of class @Ix@, if desired. % An implementation is not required to check that an index % lies within the bounds of an array when accessing that array. \subsection{Deriving Instances of @Ix@} \index{Ix@@{\tt Ix}!derived instance} It is possible to derive an instance of @Ix@ automatically, using a @deriving@ clause on a @data@ declaration (Section~4.3.3 of the Language Report). Such derived instance declarations for the class @Ix@ are only possible for enumerations\index{enumeration} (i.e.~datatypes having only nullary constructors) and single-constructor datatypes, whose constituent types are instances of @Ix@. A Haskell implementation must provide @Ix@ instances for tuples up to at least size 15. \begin{itemize} \item For an {\em enumeration}, the nullary constructors are assumed to be numbered left-to-right with the indices being $0$ to $n-1\/$ inclusive. This is the same numbering defined by the @Enum@ class. For example, given the datatype: \bprog @ data Colour = Red | Orange | Yellow | Green | Blue | Indigo | Violet @ \eprog we would have: \bprog @ range (Yellow,Blue) == [Yellow,Green,Blue] index (Yellow,Blue) Green == 1 inRange (Yellow,Blue) Red == False @ \eprog \item For {\em single-constructor datatypes}, the derived instance declarations are as shown for tuples in Figure~\ref{prelude-index}. \end{itemize} \begin{figure}[tb] \outline{ @ instance (Ix a, Ix b) => Ix (a,b) where range ((l,l'),(u,u')) = [(i,i') | i <- range (l,u), i' <- range (l',u')] index ((l,l'),(u,u')) (i,i') = index (l,u) i * rangeSize (l',u') + index (l',u') i' inRange ((l,l'),(u,u')) (i,i') = inRange (l,u) i && inRange (l',u') i' -- Instances for other tuples are obtained from this scheme: -- -- instance (Ix a1, Ix a2, ... , Ix ak) => Ix (a1,a2,...,ak) where -- range ((l1,l2,...,lk),(u1,u2,...,uk)) = -- [(i1,i2,...,ik) | i1 <- range (l1,u1), -- i2 <- range (l2,u2), -- ... -- ik <- range (lk,uk)] -- -- index ((l1,l2,...,lk),(u1,u2,...,uk)) (i1,i2,...,ik) = -- index (lk,uk) ik + rangeSize (lk,uk) * ( -- index (lk-1,uk-1) ik-1 + rangeSize (lk-1,uk-1) * ( -- ... -- index (l1,u1))) -- -- inRange ((l1,l2,...lk),(u1,u2,...,uk)) (i1,i2,...,ik) = -- inRange (l1,u1) i1 && inRange (l2,u2) i2 && -- ... && inRange (lk,uk) ik @ } \ecaption{Derivation of Ix instances} \label{prelude-index} \indextt{Ix} \indextt{range}\indextt{index}\indextt{inRange} \indextt{rangeSize} \end{figure} \clearpage \subsection{Library {\tt Ix}} \inputHS{code/Ix} %**~footer haskell98-report-20080907/libraries/array.verb0000644000175000017500000001541411345221572020417 0ustar marcotmarcot%**The Haskell 98 Library Report: Arrays %**~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 (i.e.~$\bot$). 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 @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] \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'),(_,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) @ } \ecaption{Derived array examples} \label{derived-array-examples} \end{figure} \subsection{Library {\tt Array}} \label {Libarray} \inputHS{code/Array} %**~footer haskell98-report-20080907/libraries/complex.verb0000644000175000017500000000335211345221572020746 0ustar marcotmarcot%**The Haskell 98 Library Report: Complex Numbers %**~header \section{Complex Numbers} \label{lib-num} \outline{ \inputHS{headers/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{code/Complex} %**~footer haskell98-report-20080907/libraries/numeric.verb0000644000175000017500000000723411345221573020745 0ustar marcotmarcot%**The Haskell 98 Library Report: Numerics %**~header \section{Numeric} \label{lib-numeric} \outline{ \inputHS{headers/Numeric} } This library contains assorted numeric functions, many of which are used in the standard Prelude. In what follows, recall the following type definitions from the @Prelude@: \bprog @ type ShowS = String -> String type ReadS = String -> [(a,String)] @ \eprog \subsection{Showing functions} \begin{itemize} \item @showSigned :: (Real a) => (a -> ShowS) -> Int -> a -> ShowS@ \\ converts a possibly-negative @Real@ value of type @a@ to a string. In the call "(@showSigned@ ~show ~prec ~val)", "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 @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@ \\ @ :: (RealFloat a) => Maybe Int -> a -> ShowS@ \\ These three functions all show signed @RealFloat@ values: \begin{itemize} \item @showFFloat@ uses standard decimal notation (e.g. @245000@, @0.0015@). \item @showEFloat@ uses scientific (exponential) notation (e.g. @2.45e2@, @1.5e-3@). \item @showGFloat@ uses standard decimal notation for arguments whose absolute value lies between @0.1@ and @9,999,999@, and scientific notation otherwise. \end{itemize} In the call "(@showEFloat@ ~digs ~val)", if "digs" is @Nothing@, the value is shown to full precision; if "digs" is "@Just@~ d", then at most "d" digits after the decimal point are shown. Exactly the same applies to the "digs" argument of the other two functions. \item @floatToDigits :: (RealFloat a) => Integer -> a -> ([Int], Int)@ \\ converts a base and a value to the representation of the value in digits, plus an exponent. More specifically, if $$ @floatToDigits@~b~r = @([@d_1, d_2, ... d_n@], @e@)@ $$ then the following properties hold: \begin{itemize} \item $r = 0.d_1 d_2 ..., d_n ~*~ b^e$ \item $n \geq 0$ \item $d_1 \neq 0 ~ \mbox{(when $n > 0$)}$ \item $0 \leq d_i \leq b-1$ \end{itemize} \end{itemize} \subsection{Reading functions} \begin{itemize} \item @readSigned :: (Real a) => ReadS a -> ReadS a@ \\ reads a {\em signed} @Real@ value, given a reader for an unsigned value. \item @readInt :: (Integral a) => a -> (Char->Bool) -> (Char->Int) -> ReadS a@ \\ reads an {\em unsigned} @Integral@ value in an arbitrary base. In the call "(@readInt@~ base ~isdig ~d2i)", "base" is the base, "isdig" is a predicate distinguishing valid digits in this base, and "d2i" converts a valid digit character to an @Int@. \item @readFloat :: (RealFrac a) => ReadS a@ \\ reads an {\em unsigned} @RealFrac@ value, expressed in decimal scientific notation. \item @readDec, readOct, readHex :: (Integral a) => ReadS a@ \\ each read an unsigned number, in decimal, octal, and hexadecimal notation respectively. 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} \begin{itemize} \item @fromRat :: (RealFloat a) => Rational -> a@ converts a @Rational@ value into any type in class @RealFloat@. \end{itemize} \subsection{Library {\tt Numeric}} \inputHS{code/Numeric} %**~footer haskell98-report-20080907/libraries/code/0000755000175000017500000000000011345221572017326 5ustar marcotmarcothaskell98-report-20080907/libraries/code/Numeric.hs0000644000175000017500000003103611345221572021267 0ustar marcotmarcotmodule Numeric(fromRat, showSigned, showIntAtBase, showInt, showOct, showHex, readSigned, readInt, readDec, readOct, readHex, floatToDigits, showEFloat, showFFloat, showGFloat, showFloat, readFloat, lexDigits) where import Char ( isDigit, isOctDigit, isHexDigit , digitToInt, intToDigit ) import Ratio ( (%), numerator, denominator ) import Array ( (!), Array, array ) -- This converts a rational to a floating. This should be used in the -- Fractional instances of Float and Double. fromRat :: (RealFloat a) => Rational -> a fromRat x = if x == 0 then encodeFloat 0 0 -- Handle exceptional cases else if x < 0 then - fromRat' (-x) -- first. else fromRat' x -- Conversion process: -- Scale the rational number by the RealFloat base until -- it lies in the range of the mantissa (as used by decodeFloat/encodeFloat). -- Then round the rational to an Integer and encode it with the exponent -- that we got from the scaling. -- To speed up the scaling process we compute the log2 of the number to get -- a first guess of the exponent. fromRat' :: (RealFloat a) => Rational -> a fromRat' x = r where b = floatRadix r p = floatDigits r (minExp0, _) = floatRange r minExp = minExp0 - p -- the real minimum exponent xMin = toRational (expt b (p-1)) xMax = toRational (expt b p) p0 = (integerLogBase b (numerator x) - integerLogBase b (denominator x) - p) `max` minExp f = if p0 < 0 then 1 % expt b (-p0) else expt b p0 % 1 (x', p') = scaleRat (toRational b) minExp xMin xMax p0 (x / f) r = encodeFloat (round x') p' -- Scale x until xMin <= x < xMax, or p (the exponent) <= minExp. scaleRat :: Rational -> Int -> Rational -> Rational -> Int -> Rational -> (Rational, Int) scaleRat b minExp xMin xMax p x = if p <= minExp then (x, p) else if x >= xMax then scaleRat b minExp xMin xMax (p+1) (x/b) else if x < xMin then scaleRat b minExp xMin xMax (p-1) (x*b) else (x, p) -- Exponentiation with a cache for the most common numbers. minExpt = 0::Int maxExpt = 1100::Int expt :: Integer -> Int -> Integer expt base n = if base == 2 && n >= minExpt && n <= maxExpt then expts!n else base^n expts :: Array Int Integer expts = array (minExpt,maxExpt) [(n,2^n) | n <- [minExpt .. maxExpt]] -- Compute the (floor of the) log of i in base b. -- Simplest way would be just divide i by b until it's smaller then b, -- but that would be very slow! We are just slightly more clever. integerLogBase :: Integer -> Integer -> Int integerLogBase b i = if i < b then 0 else -- Try squaring the base first to cut down the number of divisions. let l = 2 * integerLogBase (b*b) i doDiv :: Integer -> Int -> Int doDiv i l = if i < b then l else doDiv (i `div` b) (l+1) in doDiv (i `div` (b^l)) l -- 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, 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 readSigned readPos = readParen False read' where read' r = read'' r ++ [(-x,t) | ("-",s) <- lex r, (x,t) <- read'' s] read'' r = [(n,s) | (str,s) <- lex r, (n,"") <- readPos str] -- readInt reads a string of digits using an arbitrary base. -- Leading minus signs must be handled elsewhere. readInt :: (Integral a) => a -> (Char -> Bool) -> (Char -> Int) -> ReadS a readInt radix isDig digToInt s = [(foldl1 (\n d -> n * radix + d) (map (fromIntegral . digToInt) ds), r) | (ds,r) <- nonnull isDig s ] -- Unsigned readers for various bases readDec, readOct, readHex :: (Integral a) => ReadS a readDec = readInt 10 isDigit digitToInt readOct = readInt 8 isOctDigit digitToInt readHex = readInt 16 isHexDigit digitToInt showEFloat :: (RealFloat a) => Maybe Int -> a -> ShowS showFFloat :: (RealFloat a) => Maybe Int -> a -> ShowS showGFloat :: (RealFloat a) => Maybe Int -> a -> ShowS showFloat :: (RealFloat a) => a -> ShowS showEFloat d x = showString (formatRealFloat FFExponent d x) showFFloat d x = showString (formatRealFloat FFFixed d x) showGFloat d x = showString (formatRealFloat FFGeneric d x) showFloat = showGFloat Nothing -- These are the format types. This type is not exported. data FFFormat = FFExponent | FFFixed | FFGeneric formatRealFloat :: (RealFloat a) => FFFormat -> Maybe Int -> a -> String formatRealFloat fmt decs x = s where base = 10 s = if isNaN x then "NaN" else if isInfinite x then if x < 0 then "-Infinity" else "Infinity" else if x < 0 || isNegativeZero x then '-' : doFmt fmt (floatToDigits (toInteger base) (-x)) else doFmt fmt (floatToDigits (toInteger base) x) doFmt fmt (is, e) = let ds = map intToDigit is in case fmt of FFGeneric -> doFmt (if e < 0 || e > 7 then FFExponent else FFFixed) (is, e) FFExponent -> case decs of Nothing -> case ds of [] -> "0.0e0" [d] -> d : ".0e" ++ show (e-1) d:ds -> d : '.' : ds ++ 'e':show (e-1) Just dec -> let dec' = max dec 1 in case is of [] -> '0':'.':take dec' (repeat '0') ++ "e0" _ -> let (ei, is') = roundTo base (dec'+1) is d:ds = map intToDigit (if ei > 0 then init is' else is') in d:'.':ds ++ "e" ++ show (e-1+ei) FFFixed -> case decs of Nothing -- Always prints a decimal point | e > 0 -> take e (ds ++ repeat '0') ++ '.' : mk0 (drop e ds) | otherwise -> "0." ++ mk0 (replicate (-e) '0' ++ ds) Just dec -> -- Print decimal point iff dec > 0 let dec' = max dec 0 in if e >= 0 then let (ei, is') = roundTo base (dec' + e) is (ls, rs) = splitAt (e+ei) (map intToDigit is') in mk0 ls ++ mkdot0 rs else let (ei, is') = roundTo base dec' (replicate (-e) 0 ++ is) d : ds = map intToDigit (if ei > 0 then is' else 0:is') in d : mkdot0 ds where mk0 "" = "0" -- Print 0.34, not .34 mk0 s = s mkdot0 "" = "" -- Print 34, not 34. mkdot0 s = '.' : s -- when the format specifies no -- digits after the decimal point roundTo :: Int -> Int -> [Int] -> (Int, [Int]) roundTo base d is = case f d is of (0, is) -> (0, is) (1, is) -> (1, 1 : is) where b2 = base `div` 2 f n [] = (0, replicate n 0) f 0 (i:_) = (if i >= b2 then 1 else 0, []) f d (i:is) = let (c, ds) = f (d-1) is i' = c + i in if i' == base then (1, 0:ds) else (0, i':ds) -- -- Based on "Printing Floating-Point Numbers Quickly and Accurately" -- by R.G. Burger and R. K. Dybvig, in PLDI 96. -- The version here uses a much slower logarithm estimator. -- It should be improved. -- This function returns a non-empty list of digits (Ints in [0..base-1]) -- and an exponent. In general, if -- floatToDigits r = ([a, b, ... z], e) -- then -- r = 0.ab..z * base^e -- floatToDigits :: (RealFloat a) => Integer -> a -> ([Int], Int) floatToDigits _ 0 = ([], 0) floatToDigits base x = let (f0, e0) = decodeFloat x (minExp0, _) = floatRange x p = floatDigits x b = floatRadix x minExp = minExp0 - p -- the real minimum exponent -- Haskell requires that f be adjusted so denormalized numbers -- will have an impossibly low exponent. Adjust for this. f :: Integer e :: Int (f, e) = let n = minExp - e0 in if n > 0 then (f0 `div` (b^n), e0+n) else (f0, e0) (r, s, mUp, mDn) = if e >= 0 then let be = b^e in if f == b^(p-1) then (f*be*b*2, 2*b, be*b, b) else (f*be*2, 2, be, be) else if e > minExp && f == b^(p-1) then (f*b*2, b^(-e+1)*2, b, 1) else (f*2, b^(-e)*2, 1, 1) k = let k0 = if b==2 && base==10 then -- logBase 10 2 is slightly bigger than 3/10 so -- the following will err on the low side. Ignoring -- the fraction will make it err even more. -- Haskell promises that p-1 <= logBase b f < p. (p - 1 + e0) * 3 `div` 10 else ceiling ((log (fromInteger (f+1)) + fromIntegral e * log (fromInteger b)) / log (fromInteger base)) fixup n = if n >= 0 then if r + mUp <= expt base n * s then n else fixup (n+1) else if expt base (-n) * (r + mUp) <= s then n else fixup (n+1) in fixup k0 gen ds rn sN mUpN mDnN = let (dn, rn') = (rn * base) `divMod` sN mUpN' = mUpN * base mDnN' = mDnN * base in case (rn' < mDnN', rn' + mUpN' > sN) of (True, False) -> dn : ds (False, True) -> dn+1 : ds (True, True) -> if rn' * 2 < sN then dn : ds else dn+1 : ds (False, False) -> gen (dn:ds) rn' sN mUpN' mDnN' rds = if k >= 0 then gen [] r (s * expt base k) mUp mDn else let bk = expt base (-k) in gen [] (r * bk) s (mUp * bk) (mDn * bk) in (map fromIntegral (reverse rds), k) -- This floating point reader uses a less restrictive syntax for floating -- point than the Haskell lexer. The `.' is optional. readFloat :: (RealFrac a) => ReadS a readFloat r = [(fromRational ((n%1)*10^^(k-d)),t) | (n,d,s) <- readFix r, (k,t) <- readExp s] ++ [ (0/0, t) | ("NaN",t) <- lex r] ++ [ (1/0, t) | ("Infinity",t) <- lex r] where readFix r = [(read (ds++ds'), length ds', t) | (ds,d) <- lexDigits r, (ds',t) <- lexFrac d ] lexFrac ('.':ds) = lexDigits ds lexFrac s = [("",s)] readExp (e:s) | e `elem` "eE" = readExp' s readExp s = [(0,s)] readExp' ('-':s) = [(-k,t) | (k,t) <- readDec s] readExp' ('+':s) = readDec s readExp' s = readDec s lexDigits :: ReadS String lexDigits = nonnull isDigit nonnull :: (Char -> Bool) -> ReadS String nonnull p s = [(cs,t) | (cs@(_:_),t) <- [span p s]] haskell98-report-20080907/libraries/code/Random.hs0000644000175000017500000000611711345221572021107 0ustar marcotmarcotmodule Random ( RandomGen(next, split, genRange), StdGen, mkStdGen, Random( random, randomR, randoms, randomRs, randomIO, randomRIO ), getStdRandom, getStdGen, setStdGen, newStdGen ) where ---------------- The RandomGen class --------------------------- class RandomGen g where genRange :: g -> (Int, Int) next :: g -> (Int, g) split :: g -> (g, g) -- May not exist for all RandomGens ---------------- A standard instance of RandomGen --------------- data StdGen = ... -- Abstract instance RandomGen StdGen where ... -- The show/read instances provide a primitive way to save -- the state of a random number generator -- It is expected read (show g) == g instance Read StdGen where ... -- read succeeds on *any* string, not only those -- constructed with show. Hence you can use any -- string as way to construct a RandomGen. -- - read guarantees to consume a finite portion of -- the string -- - different strings are likely to result in -- different generators instance Show StdGen where ... mkStdGen :: Int -> StdGen -- Make a StdGen from an Int. Different Ints should result -- in different generators. ---------------- The Random class --------------------------- class Random a where randomR :: RandomGen g => (a, a) -> g -> (a, g) -- Returns a random value uniformly distributed in [lo,hi] -- It is unspecified what happens if lo > hi random :: RandomGen g => g -> (a, g) -- Return any value of type a. -- For bounded types, the range is normally the whole type -- For Fractional types, the range is normally [0..1] -- For Integer, the range is (arbitrarily) the range of Int randomRs :: RandomGen g => (a, a) -> g -> [a] randoms :: RandomGen g => g -> [a] randomIO :: IO a randomRIO :: (a,a) -> IO a -- Default methods randoms g = x : randoms g' where (x,g') = random g randomRs = ...similar... randomIO = getStdRandom random randomRIO range = getStdRandom (randomR range) instance Random Int where ... instance Random Integer where ... instance Random Float where ... instance Random Double where ... instance Random Bool where ... instance Random Char where ... ---------------- The global random generator --------------------------- -- There is a single, implicit, global random number generator -- of type StdGen, held in some global variable maintained by the IO monad -- -- It is initialised non-deterministically; to get -- deterministic behaviour use setStdGen. setStdGen :: StdGen -> IO () -- Set the global generator getStdGen :: IO StdGen -- Get the global generator getStdRandom :: (StdGen -> (a, StdGen)) -> IO a -- Use the supplied function to get a value from -- the current global random generator, g, and update the -- global generator with the new generator returned getStdRandom f = do g <- getStdGen let (val, g') = f g setStdGen g' return val newStdGen :: IO StdGen -- Apply split to the current global random generator -- update it with one of the results and return the other newStdGen = do g <- getStdGen let (s1,s2) = split g setStdGen s1 return s2 haskell98-report-20080907/libraries/code/Ratio.hs0000644000175000017500000000741011345221572020742 0ustar marcotmarcot-- Standard functions on rational numbers module Ratio ( Ratio, Rational, (%), numerator, denominator, approxRational ) where infixl 7 % ratPrec = 7 :: Int data (Integral a) => Ratio a = !a :% !a deriving (Eq) type Rational = Ratio Integer (%) :: (Integral a) => a -> a -> Ratio a numerator, denominator :: (Integral a) => Ratio a -> a approxRational :: (RealFrac a) => a -> a -> Rational -- "reduce" is a subsidiary function used only in this module. -- It normalises a ratio by dividing both numerator -- and denominator by their greatest common divisor. -- -- E.g., 12 `reduce` 8 == 3 :% 2 -- 12 `reduce` (-8) == 3 :% (-2) reduce _ 0 = error "Ratio.% : zero denominator" reduce x y = (x `quot` d) :% (y `quot` d) where d = gcd x y x % y = reduce (x * signum y) (abs y) numerator (x :% _) = x denominator (_ :% y) = y instance (Integral a) => Ord (Ratio a) where (x:%y) <= (x':%y') = x * y' <= x' * y (x:%y) < (x':%y') = x * y' < x' * y instance (Integral a) => Num (Ratio a) where (x:%y) + (x':%y') = reduce (x*y' + x'*y) (y*y') (x:%y) * (x':%y') = reduce (x * x') (y * y') negate (x:%y) = (-x) :% y abs (x:%y) = abs x :% y signum (x:%y) = signum x :% 1 fromInteger x = fromInteger x :% 1 instance (Integral a) => Real (Ratio a) where toRational (x:%y) = toInteger x :% toInteger y instance (Integral a) => Fractional (Ratio a) where (x:%y) / (x':%y') = (x*y') % (y*x') recip (x:%y) = y % x fromRational (x:%y) = fromInteger x :% fromInteger y instance (Integral a) => RealFrac (Ratio a) where properFraction (x:%y) = (fromIntegral q, r:%y) where (q,r) = quotRem x y instance (Integral a) => Enum (Ratio a) where succ x = x+1 pred x = x-1 toEnum = fromIntegral fromEnum = fromInteger . truncate -- May overflow enumFrom = numericEnumFrom -- These numericEnumXXX functions enumFromThen = numericEnumFromThen -- are as defined in Prelude.hs enumFromTo = numericEnumFromTo -- but not exported from it! enumFromThenTo = numericEnumFromThenTo instance (Read a, Integral a) => Read (Ratio a) where readsPrec p = readParen (p > ratPrec) (\r -> [(x%y,u) | (x,s) <- readsPrec (ratPrec+1) r, ("%",t) <- lex s, (y,u) <- readsPrec (ratPrec+1) t ]) instance (Integral a) => Show (Ratio a) where showsPrec p (x:%y) = showParen (p > ratPrec) (showsPrec (ratPrec+1) x . showString " % " . showsPrec (ratPrec+1) y) approxRational x eps = simplest (x-eps) (x+eps) where simplest x y | y < x = simplest y x | x == y = xr | x > 0 = simplest' n d n' d' | y < 0 = - simplest' (-n') d' (-n) d | otherwise = 0 :% 1 where xr@(n:%d) = toRational x (n':%d') = toRational y simplest' n d n' d' -- assumes 0 < n%d < n'%d' | r == 0 = q :% 1 | q /= q' = (q+1) :% 1 | otherwise = (q*n''+d'') :% n'' where (q,r) = quotRem n d (q',r') = quotRem n' d' (n'':%d'') = simplest' d' r' d r haskell98-report-20080907/libraries/code/Monad.hs0000644000175000017500000000554611345221572020732 0ustar marcotmarcotmodule Monad ( MonadPlus(mzero, mplus), join, guard, when, unless, ap, msum, filterM, mapAndUnzipM, zipWithM, zipWithM_, foldM, liftM, liftM2, liftM3, liftM4, liftM5, -- ...and what the Prelude exports Monad((>>=), (>>), return, fail), Functor(fmap), mapM, mapM_, sequence, sequence_, (=<<), ) where -- The MonadPlus class definition class (Monad m) => MonadPlus m where mzero :: m a mplus :: m a -> m a -> m a -- Instances of MonadPlus instance MonadPlus Maybe where mzero = Nothing Nothing `mplus` ys = ys xs `mplus` ys = xs instance MonadPlus [] where mzero = [] mplus = (++) -- Functions msum :: MonadPlus m => [m a] -> m a msum xs = foldr mplus mzero xs join :: (Monad m) => m (m a) -> m a join x = x >>= id when :: (Monad m) => Bool -> m () -> m () when p s = if p then s else return () unless :: (Monad m) => Bool -> m () -> m () unless p s = when (not p) s ap :: (Monad m) => m (a -> b) -> m a -> m b ap = liftM2 ($) guard :: MonadPlus m => Bool -> m () guard p = if p then return () else mzero mapAndUnzipM :: (Monad m) => (a -> m (b,c)) -> [a] -> m ([b], [c]) mapAndUnzipM f xs = sequence (map f xs) >>= return . unzip zipWithM :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m [c] zipWithM f xs ys = sequence (zipWith f xs ys) zipWithM_ :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m () zipWithM_ f xs ys = sequence_ (zipWith f xs ys) foldM :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a foldM f a [] = return a foldM f a (x:xs) = f a x >>= \ y -> foldM f y xs filterM :: Monad m => (a -> m Bool) -> [a] -> m [a] filterM p [] = return [] filterM p (x:xs) = do { b <- p x; ys <- filterM p xs; return (if b then (x:ys) else ys) } liftM :: (Monad m) => (a -> b) -> (m a -> m b) liftM f = \a -> do { a' <- a; return (f a') } liftM2 :: (Monad m) => (a -> b -> c) -> (m a -> m b -> m c) liftM2 f = \a b -> do { a' <- a; b' <- b; return (f a' b') } liftM3 :: (Monad m) => (a -> b -> c -> d) -> (m a -> m b -> m c -> m d) liftM3 f = \a b c -> do { a' <- a; b' <- b; c' <- c; return (f a' b' c') } liftM4 :: (Monad m) => (a -> b -> c -> d -> e) -> (m a -> m b -> m c -> m d -> m e) liftM4 f = \a b c d -> do { a' <- a; b' <- b; c' <- c; d' <- d; return (f a' b' c' d') } liftM5 :: (Monad m) => (a -> b -> c -> d -> e -> f) -> (m a -> m b -> m c -> m d -> m e -> m f) liftM5 f = \a b c d e -> do { a' <- a; b' <- b; c' <- c; d' <- d; e' <- e; return (f a' b' c' d' e') } haskell98-report-20080907/libraries/code/Maybe.hs0000644000175000017500000000175411345221572020726 0ustar marcotmarcotmodule Maybe( isJust, isNothing, fromJust, fromMaybe, listToMaybe, maybeToList, catMaybes, mapMaybe, -- ...and what the Prelude exports Maybe(Nothing, Just), maybe ) where isJust :: Maybe a -> Bool isJust (Just a) = True isJust Nothing = False isNothing :: Maybe a -> Bool isNothing = not . isJust fromJust :: Maybe a -> a fromJust (Just a) = a fromJust Nothing = error "Maybe.fromJust: Nothing" fromMaybe :: a -> Maybe a -> a fromMaybe d Nothing = d fromMaybe d (Just a) = a maybeToList :: Maybe a -> [a] maybeToList Nothing = [] maybeToList (Just a) = [a] listToMaybe :: [a] -> Maybe a listToMaybe [] = Nothing listToMaybe (a:_) = Just a catMaybes :: [Maybe a] -> [a] catMaybes ms = [ m | Just m <- ms ] mapMaybe :: (a -> Maybe b) -> [a] -> [b] mapMaybe f = catMaybes . map f haskell98-report-20080907/libraries/code/Complex.hs0000644000175000017500000000643411345221572021300 0ustar marcotmarcot module Complex(Complex((:+)), realPart, imagPart, conjugate, mkPolar, cis, polar, magnitude, phase) where infix 6 :+ data (RealFloat a) => Complex a = !a :+ !a deriving (Eq,Read,Show) realPart, imagPart :: (RealFloat a) => Complex a -> a realPart (x:+y) = x imagPart (x:+y) = y conjugate :: (RealFloat a) => Complex a -> Complex a conjugate (x:+y) = x :+ (-y) mkPolar :: (RealFloat a) => a -> a -> Complex a mkPolar r theta = r * cos theta :+ r * sin theta cis :: (RealFloat a) => a -> Complex a cis theta = cos theta :+ sin theta polar :: (RealFloat a) => Complex a -> (a,a) polar z = (magnitude z, phase z) magnitude :: (RealFloat a) => Complex a -> a magnitude (x:+y) = scaleFloat k (sqrt ((scaleFloat mk x)^2 + (scaleFloat mk y)^2)) where k = max (exponent x) (exponent y) mk = - k phase :: (RealFloat a) => Complex a -> a phase (0 :+ 0) = 0 phase (x :+ y) = atan2 y x instance (RealFloat a) => Num (Complex a) where (x:+y) + (x':+y') = (x+x') :+ (y+y') (x:+y) - (x':+y') = (x-x') :+ (y-y') (x:+y) * (x':+y') = (x*x'-y*y') :+ (x*y'+y*x') negate (x:+y) = negate x :+ negate y abs z = magnitude z :+ 0 signum 0 = 0 signum z@(x:+y) = x/r :+ y/r where r = magnitude z fromInteger n = fromInteger n :+ 0 instance (RealFloat a) => Fractional (Complex a) where (x:+y) / (x':+y') = (x*x''+y*y'') / d :+ (y*x''-x*y'') / d where x'' = scaleFloat k x' y'' = scaleFloat k y' k = - max (exponent x') (exponent y') d = x'*x'' + y'*y'' fromRational a = fromRational a :+ 0 instance (RealFloat a) => Floating (Complex a) where pi = pi :+ 0 exp (x:+y) = expx * cos y :+ expx * sin y where expx = exp x log z = log (magnitude z) :+ phase z sqrt 0 = 0 sqrt z@(x:+y) = u :+ (if y < 0 then -v else v) where (u,v) = if x < 0 then (v',u') else (u',v') v' = abs y / (u'*2) u' = sqrt ((magnitude z + abs x) / 2) sin (x:+y) = sin x * cosh y :+ cos x * sinh y cos (x:+y) = cos x * cosh y :+ (- sin x * sinh y) tan (x:+y) = (sinx*coshy:+cosx*sinhy)/(cosx*coshy:+(-sinx*sinhy)) where sinx = sin x cosx = cos x sinhy = sinh y coshy = cosh y sinh (x:+y) = cos y * sinh x :+ sin y * cosh x cosh (x:+y) = cos y * cosh x :+ sin y * sinh x tanh (x:+y) = (cosy*sinhx:+siny*coshx)/(cosy*coshx:+siny*sinhx) where siny = sin y cosy = cos y sinhx = sinh x coshx = cosh x asin z@(x:+y) = y':+(-x') where (x':+y') = log (((-y):+x) + sqrt (1 - z*z)) acos z@(x:+y) = y'':+(-x'') where (x'':+y'') = log (z + ((-y'):+x')) (x':+y') = sqrt (1 - z*z) atan z@(x:+y) = y':+(-x') where (x':+y') = log (((1-y):+x) / sqrt (1+z*z)) asinh z = log (z + sqrt (1+z*z)) acosh z = log (z + (z+1) * sqrt ((z-1)/(z+1))) atanh z = log ((1+z) / sqrt (1-z*z)) haskell98-report-20080907/libraries/code/Locale.hs0000644000175000017500000000240711345221572021064 0ustar marcotmarcotmodule Locale(TimeLocale(..), defaultTimeLocale) where data TimeLocale = TimeLocale { wDays :: [(String, String)], -- full and abbreviated week days months :: [(String, String)], -- full and abbreviated months amPm :: (String, String), -- AM/PM symbols dateTimeFmt, dateFmt, -- formatting strings timeFmt, time12Fmt :: String } deriving (Eq, Ord, Show) defaultTimeLocale :: TimeLocale defaultTimeLocale = TimeLocale { wDays = [("Sunday", "Sun"), ("Monday", "Mon"), ("Tuesday", "Tue"), ("Wednesday", "Wed"), ("Thursday", "Thu"), ("Friday", "Fri"), ("Saturday", "Sat")], months = [("January", "Jan"), ("February", "Feb"), ("March", "Mar"), ("April", "Apr"), ("May", "May"), ("June", "Jun"), ("July", "Jul"), ("August", "Aug"), ("September", "Sep"), ("October", "Oct"), ("November", "Nov"), ("December", "Dec")], amPm = ("AM", "PM"), dateTimeFmt = "%a %b %e %H:%M:%S %Z %Y", dateFmt = "%m/%d/%y", timeFmt = "%H:%M:%S", time12Fmt = "%I:%M:%S %p" } haskell98-report-20080907/libraries/code/List.hs0000644000175000017500000002520111345221572020575 0ustar marcotmarcotmodule List ( elemIndex, elemIndices, find, findIndex, findIndices, nub, nubBy, delete, deleteBy, (\\), deleteFirstsBy, union, unionBy, intersect, intersectBy, intersperse, transpose, partition, group, groupBy, inits, tails, isPrefixOf, isSuffixOf, mapAccumL, mapAccumR, sort, sortBy, insert, insertBy, maximumBy, minimumBy, genericLength, genericTake, genericDrop, genericSplitAt, genericIndex, genericReplicate, zip4, zip5, zip6, zip7, zipWith4, zipWith5, zipWith6, zipWith7, 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, iterate, repeat, replicate, cycle, take, drop, splitAt, takeWhile, dropWhile, span, break, lines, words, unlines, unwords, reverse, and, or, any, all, elem, notElem, lookup, sum, product, maximum, minimum, concatMap, zip, zip3, zipWith, zipWith3, unzip, unzip3 ) where import Maybe( listToMaybe ) infix 5 \\ elemIndex :: Eq a => a -> [a] -> Maybe Int elemIndex x = findIndex (x ==) elemIndices :: Eq a => a -> [a] -> [Int] elemIndices x = findIndices (x ==) find :: (a -> Bool) -> [a] -> Maybe a find p = listToMaybe . filter p findIndex :: (a -> Bool) -> [a] -> Maybe Int findIndex p = listToMaybe . findIndices p findIndices :: (a -> Bool) -> [a] -> [Int] findIndices p xs = [ i | (x,i) <- zip xs [0..], p x ] nub :: Eq a => [a] -> [a] nub = nubBy (==) nubBy :: (a -> a -> Bool) -> [a] -> [a] nubBy eq [] = [] nubBy eq (x:xs) = x : nubBy eq (filter (\y -> not (eq x y)) xs) delete :: Eq a => a -> [a] -> [a] delete = deleteBy (==) deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a] deleteBy eq x [] = [] deleteBy eq x (y:ys) = if x `eq` y then ys else y : deleteBy eq x ys (\\) :: Eq a => [a] -> [a] -> [a] (\\) = foldl (flip delete) deleteFirstsBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] deleteFirstsBy eq = foldl (flip (deleteBy eq)) union :: Eq a => [a] -> [a] -> [a] union = unionBy (==) unionBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] unionBy eq xs ys = xs ++ deleteFirstsBy eq (nubBy eq ys) xs intersect :: Eq a => [a] -> [a] -> [a] intersect = intersectBy (==) intersectBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] intersectBy eq xs ys = [x | x <- xs, any (eq x) ys] intersperse :: a -> [a] -> [a] intersperse sep [] = [] 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' -- 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 transpose :: [[a]] -> [[a]] transpose [] = [] transpose ([] : xss) = transpose xss transpose ((x:xs) : xss) = (x : [h | (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) -- group splits its list argument into a list of lists of equal, adjacent -- elements. e.g., -- group "Mississippi" == ["M","i","ss","i","ss","i","pp","i"] group :: Eq a => [a] -> [[a]] group = groupBy (==) groupBy :: (a -> a -> Bool) -> [a] -> [[a]] groupBy eq [] = [] groupBy eq (x:xs) = (x:ys) : groupBy eq zs where (ys,zs) = span (eq x) xs -- inits xs returns the list of initial segments of xs, shortest first. -- e.g., inits "abc" == ["","a","ab","abc"] inits :: [a] -> [[a]] inits [] = [[]] inits (x:xs) = [[]] ++ map (x:) (inits xs) -- tails xs returns the list of all final segments of xs, longest first. -- e.g., tails "abc" == ["abc", "bc", "c",""] tails :: [a] -> [[a]] tails [] = [[]] tails xxs@(_:xs) = xxs : tails xs isPrefixOf :: Eq a => [a] -> [a] -> Bool isPrefixOf [] _ = True isPrefixOf _ [] = False isPrefixOf (x:xs) (y:ys) = x == y && isPrefixOf xs ys isSuffixOf :: Eq a => [a] -> [a] -> Bool isSuffixOf x y = reverse x `isPrefixOf` reverse y mapAccumL :: (a -> b -> (a, c)) -> a -> [b] -> (a, [c]) mapAccumL f s [] = (s, []) mapAccumL f s (x:xs) = (s'',y:ys) where (s', y ) = f s x (s'',ys) = mapAccumL f s' xs mapAccumR :: (a -> b -> (a, c)) -> a -> [b] -> (a, [c]) mapAccumR f s [] = (s, []) 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 sort :: (Ord a) => [a] -> [a] sort = sortBy compare sortBy :: (a -> a -> Ordering) -> [a] -> [a] sortBy cmp = foldr (insertBy cmp) [] insert :: (Ord a) => a -> [a] -> [a] insert = insertBy compare insertBy :: (a -> a -> Ordering) -> a -> [a] -> [a] insertBy cmp x [] = [x] insertBy cmp x ys@(y:ys') = case cmp x y of GT -> y : insertBy cmp x ys' _ -> x : 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 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 genericLength :: (Integral a) => [b] -> a genericLength [] = 0 genericLength (x:xs) = 1 + genericLength xs genericTake :: (Integral a) => a -> [b] -> [b] genericTake _ [] = [] genericTake 0 _ = [] genericTake n (x:xs) | n > 0 = x : genericTake (n-1) xs | otherwise = error "List.genericTake: negative argument" genericDrop :: (Integral a) => a -> [b] -> [b] genericDrop 0 xs = xs genericDrop _ [] = [] genericDrop n (_:xs) | n > 0 = genericDrop (n-1) xs | otherwise = error "List.genericDrop: negative argument" genericSplitAt :: (Integral a) => a -> [b] -> ([b],[b]) genericSplitAt 0 xs = ([],xs) genericSplitAt _ [] = ([],[]) genericSplitAt n (x:xs) | n > 0 = (x:xs',xs'') | otherwise = error "List.genericSplitAt: negative argument" where (xs',xs'') = genericSplitAt (n-1) xs genericIndex :: (Integral a) => [b] -> a -> b genericIndex (x:_) 0 = x genericIndex (_:xs) n | n > 0 = genericIndex xs (n-1) | otherwise = error "List.genericIndex: negative argument" genericIndex _ _ = error "List.genericIndex: index too large" genericReplicate :: (Integral a) => a -> b -> [b] genericReplicate n x = genericTake n (repeat x) zip4 :: [a] -> [b] -> [c] -> [d] -> [(a,b,c,d)] zip4 = zipWith4 (,,,) zip5 :: [a] -> [b] -> [c] -> [d] -> [e] -> [(a,b,c,d,e)] zip5 = zipWith5 (,,,,) zip6 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [(a,b,c,d,e,f)] zip6 = zipWith6 (,,,,,) zip7 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g] -> [(a,b,c,d,e,f,g)] zip7 = zipWith7 (,,,,,,) zipWith4 :: (a->b->c->d->e) -> [a]->[b]->[c]->[d]->[e] zipWith4 z (a:as) (b:bs) (c:cs) (d:ds) = z a b c d : zipWith4 z as bs cs ds zipWith4 _ _ _ _ _ = [] zipWith5 :: (a->b->c->d->e->f) -> [a]->[b]->[c]->[d]->[e]->[f] zipWith5 z (a:as) (b:bs) (c:cs) (d:ds) (e:es) = z a b c d e : zipWith5 z as bs cs ds es zipWith5 _ _ _ _ _ _ = [] zipWith6 :: (a->b->c->d->e->f->g) -> [a]->[b]->[c]->[d]->[e]->[f]->[g] zipWith6 z (a:as) (b:bs) (c:cs) (d:ds) (e:es) (f:fs) = z a b c d e f : zipWith6 z as bs cs ds es fs zipWith6 _ _ _ _ _ _ _ = [] zipWith7 :: (a->b->c->d->e->f->g->h) -> [a]->[b]->[c]->[d]->[e]->[f]->[g]->[h] zipWith7 z (a:as) (b:bs) (c:cs) (d:ds) (e:es) (f:fs) (g:gs) = z a b c d e f g : zipWith7 z as bs cs ds es fs gs zipWith7 _ _ _ _ _ _ _ _ = [] unzip4 :: [(a,b,c,d)] -> ([a],[b],[c],[d]) unzip4 = foldr (\(a,b,c,d) ~(as,bs,cs,ds) -> (a:as,b:bs,c:cs,d:ds)) ([],[],[],[]) unzip5 :: [(a,b,c,d,e)] -> ([a],[b],[c],[d],[e]) unzip5 = foldr (\(a,b,c,d,e) ~(as,bs,cs,ds,es) -> (a:as,b:bs,c:cs,d:ds,e:es)) ([],[],[],[],[]) unzip6 :: [(a,b,c,d,e,f)] -> ([a],[b],[c],[d],[e],[f]) unzip6 = foldr (\(a,b,c,d,e,f) ~(as,bs,cs,ds,es,fs) -> (a:as,b:bs,c:cs,d:ds,e:es,f:fs)) ([],[],[],[],[],[]) unzip7 :: [(a,b,c,d,e,f,g)] -> ([a],[b],[c],[d],[e],[f],[g]) unzip7 = foldr (\(a,b,c,d,e,f,g) ~(as,bs,cs,ds,es,fs,gs) -> (a:as,b:bs,c:cs,d:ds,e:es,f:fs,g:gs)) ([],[],[],[],[],[],[]) haskell98-report-20080907/libraries/code/IO.hs0000644000175000017500000000147411345221572020177 0ustar marcotmarcotmodule IO {- export list omitted -} where -- Just provide an implementation of the system-independent -- actions that IO exports. try :: IO a -> IO (Either IOError a) try f = catch (do r <- f return (Right r)) (return . Left) bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c bracket before after m = do x <- before rs <- try (m x) after x case rs of Right r -> return r Left e -> ioError e -- variant of the above where middle computation doesn't want x bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c bracket_ before after m = do x <- before rs <- try m after x case rs of Right r -> return r Left e -> ioError e haskell98-report-20080907/libraries/code/Ix.hs0000644000175000017500000000256711345221572020254 0ustar marcotmarcotmodule Ix ( Ix(range, index, inRange, rangeSize) ) where class Ord a => Ix a where range :: (a,a) -> [a] index :: (a,a) -> a -> Int inRange :: (a,a) -> a -> Bool rangeSize :: (a,a) -> Int rangeSize b@(l,h) | null (range b) = 0 | otherwise = index b h + 1 -- NB: replacing "null (range b)" by "not (l <= h)" -- fails if the bounds are tuples. For example, -- (1,2) <= (2,1) -- but the range is nevertheless empty -- range ((1,2),(2,1)) = [] instance Ix Char where range (m,n) = [m..n] index b@(c,c') ci | inRange b ci = fromEnum ci - fromEnum c | otherwise = error "Ix.index: Index out of range." inRange (c,c') i = c <= i && i <= c' instance Ix Int where range (m,n) = [m..n] index b@(m,n) i | inRange b i = i - m | otherwise = error "Ix.index: Index out of range." inRange (m,n) i = m <= i && i <= n instance Ix Integer where range (m,n) = [m..n] index b@(m,n) i | inRange b i = fromInteger (i - m) | otherwise = error "Ix.index: Index out of range." inRange (m,n) i = m <= i && i <= n instance (Ix a,Ix b) => Ix (a, b) -- as derived, for all tuples instance Ix Bool -- as derived instance Ix Ordering -- as derived instance Ix () -- as derived haskell98-report-20080907/libraries/code/Time.hs0000644000175000017500000001253211345221572020563 0ustar marcotmarcotmodule Time ( ClockTime, Month(January,February,March,April,May,June, July,August,September,October,November,December), Day(Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday), CalendarTime(CalendarTime, ctYear, ctMonth, ctDay, ctHour, ctMin, ctPicosec, ctWDay, ctYDay, ctTZName, ctTZ, ctIsDST), TimeDiff(TimeDiff, tdYear, tdMonth, tdDay, tdHour, tdMin, tdSec, tdPicosec), getClockTime, addToClockTime, diffClockTimes, toCalendarTime, toUTCTime, toClockTime, calendarTimeToString, formatCalendarTime ) where import Ix(Ix) import Locale(TimeLocale(..),defaultTimeLocale) import Char ( intToDigit ) data ClockTime = ... -- Implementation-dependent instance Ord ClockTime where ... instance Eq ClockTime where ... data Month = January | February | March | April | May | June | July | August | September | October | November | December deriving (Eq, Ord, Enum, Bounded, Ix, Read, Show) data Day = Sunday | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday deriving (Eq, Ord, Enum, Bounded, Ix, Read, Show) data CalendarTime = CalendarTime { ctYear :: Int, ctMonth :: Month, ctDay, ctHour, ctMin, ctSec :: Int, ctPicosec :: Integer, ctWDay :: Day, ctYDay :: Int, ctTZName :: String, ctTZ :: Int, ctIsDST :: Bool } deriving (Eq, Ord, Read, Show) data TimeDiff = TimeDiff { tdYear, tdMonth, tdDay, tdHour, tdMin, tdSec :: Int, tdPicosec :: Integer } deriving (Eq, Ord, Read, Show) getClockTime :: IO ClockTime getClockTime = ... -- Implementation-dependent addToClockTime :: TimeDiff -> ClockTime -> ClockTime addToClockTime td ct = ... -- Implementation-dependent diffClockTimes :: ClockTime -> ClockTime -> TimeDiff diffClockTimes ct1 ct2 = ... -- Implementation-dependent toCalendarTime :: ClockTime -> IO CalendarTime toCalendarTime ct = ... -- Implementation-dependent toUTCTime :: ClockTime -> CalendarTime toUTCTime ct = ... -- Implementation-dependent toClockTime :: CalendarTime -> ClockTime toClockTime cal = ... -- Implementation-dependent calendarTimeToString :: CalendarTime -> String calendarTimeToString = formatCalendarTime defaultTimeLocale "%c" formatCalendarTime :: TimeLocale -> String -> CalendarTime -> String formatCalendarTime l fmt ct@(CalendarTime year mon day hour min sec sdec wday yday tzname _ _) = doFmt fmt where doFmt ('%':c:cs) = decode c ++ doFmt cs doFmt (c:cs) = c : doFmt cs doFmt "" = "" to12 :: Int -> Int to12 h = let h' = h `mod` 12 in if h' == 0 then 12 else h' decode 'A' = fst (wDays l !! fromEnum wday) decode 'a' = snd (wDays l !! fromEnum wday) decode 'B' = fst (months l !! fromEnum mon) decode 'b' = snd (months l !! fromEnum mon) decode 'h' = snd (months l !! fromEnum mon) decode 'C' = show2 (year `quot` 100) decode 'c' = doFmt (dateTimeFmt l) decode 'D' = doFmt "%m/%d/%y" decode 'd' = show2 day decode 'e' = show2' day decode 'H' = show2 hour decode 'I' = show2 (to12 hour) decode 'j' = show3 yday decode 'k' = show2' hour decode 'l' = show2' (to12 hour) decode 'M' = show2 min decode 'm' = show2 (fromEnum mon+1) decode 'n' = "\n" decode 'p' = (if hour < 12 then fst else snd) (amPm l) decode 'R' = doFmt "%H:%M" decode 'r' = doFmt (time12Fmt l) decode 'T' = doFmt "%H:%M:%S" decode 't' = "\t" decode 'S' = show2 sec decode 's' = ... -- Implementation-dependent decode 'U' = show2 ((yday + 7 - fromEnum wday) `div` 7) decode 'u' = show (let n = fromEnum wday in if n == 0 then 7 else n) decode 'V' = let (week, days) = (yday + 7 - if fromEnum wday > 0 then fromEnum wday - 1 else 6) `divMod` 7 in show2 (if days >= 4 then week+1 else if week == 0 then 53 else week) decode 'W' = show2 ((yday + 7 - if fromEnum wday > 0 then fromEnum wday - 1 else 6) `div` 7) decode 'w' = show (fromEnum wday) decode 'X' = doFmt (timeFmt l) decode 'x' = doFmt (dateFmt l) decode 'Y' = show year decode 'y' = show2 (year `rem` 100) decode 'Z' = tzname decode '%' = "%" decode c = [c] show2, show2', show3 :: Int -> String show2 x = [intToDigit (x `quot` 10), intToDigit (x `rem` 10)] show2' x = if x < 10 then [ ' ', intToDigit x] else show2 x show3 x = intToDigit (x `quot` 100) : show2 (x `rem` 100) haskell98-report-20080907/libraries/code/Char.hs0000644000175000017500000001243411345221572020543 0ustar marcotmarcotmodule 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. import Numeric (readDec, readOct, lexDigits, readHex) import UnicodePrims -- Source of primitive Unicode functions. -- Character-testing operations isAscii, isLatin1, isControl, isPrint, isSpace, isUpper, isLower, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum :: Char -> Bool isAscii c = c < '\x80' isLatin1 c = c <= '\xff' isControl c = c < ' ' || c >= '\DEL' && c <= '\x9f' isPrint = primUnicodeIsPrint isSpace c = c `elem` " \t\n\r\f\v\xA0" -- Only Latin-1 spaces recognized isUpper = primUnicodeIsUpper -- 'A'..'Z' isLower = primUnicodeIsLower -- 'a'..'z' isAlpha c = isUpper c || isLower c isDigit c = c >= '0' && c <= '9' isOctDigit c = c >= '0' && c <= '7' isHexDigit c = isDigit c || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f' isAlphaNum = primUnicodeIsAlphaNum -- Digit conversion operations digitToInt :: Char -> Int digitToInt c | isDigit c = fromEnum c - fromEnum '0' | c >= 'a' && c <= 'f' = fromEnum c - fromEnum 'a' + 10 | c >= 'A' && c <= 'F' = fromEnum c - fromEnum 'A' + 10 | otherwise = error "Char.digitToInt: not a digit" intToDigit :: Int -> Char intToDigit i | i >= 0 && i <= 9 = toEnum (fromEnum '0' + i) | i >= 10 && i <= 15 = toEnum (fromEnum 'a' + i - 10) | otherwise = error "Char.intToDigit: not a digit" -- Case-changing operations toUpper :: Char -> Char toUpper = primUnicodeToUpper toLower :: Char -> Char toLower = primUnicodeToLower -- Character code functions ord :: Char -> Int ord = fromEnum chr :: Int -> Char chr = toEnum -- Text functions readLitChar :: ReadS Char readLitChar ('\\':s) = readEsc s readLitChar (c:s) = [(c,s)] readEsc :: ReadS Char readEsc ('a':s) = [('\a',s)] readEsc ('b':s) = [('\b',s)] readEsc ('f':s) = [('\f',s)] readEsc ('n':s) = [('\n',s)] readEsc ('r':s) = [('\r',s)] readEsc ('t':s) = [('\t',s)] readEsc ('v':s) = [('\v',s)] readEsc ('\\':s) = [('\\',s)] readEsc ('"':s) = [('"',s)] readEsc ('\'':s) = [('\'',s)] readEsc ('^':c:s) | c >= '@' && c <= '_' = [(chr (ord c - ord '@'), s)] readEsc s@(d:_) | isDigit d = [(chr n, t) | (n,t) <- readDec s] readEsc ('o':s) = [(chr n, t) | (n,t) <- readOct s] readEsc ('x':s) = [(chr n, t) | (n,t) <- readHex s] readEsc s@(c:_) | isUpper c = let table = ('\DEL', "DEL") : assocs asciiTab in case [(c,s') | (c, mne) <- table, ([],s') <- [match mne s]] of (pr:_) -> [pr] [] -> [] readEsc _ = [] match :: (Eq a) => [a] -> [a] -> ([a],[a]) match (x:xs) (y:ys) | x == y = match xs ys match xs ys = (xs,ys) showLitChar :: Char -> ShowS showLitChar c | c > '\DEL' = showChar '\\' . protectEsc isDigit (shows (ord c)) showLitChar '\DEL' = showString "\\DEL" showLitChar '\\' = showString "\\\\" showLitChar c | c >= ' ' = showChar c showLitChar '\a' = showString "\\a" showLitChar '\b' = showString "\\b" showLitChar '\f' = showString "\\f" showLitChar '\n' = showString "\\n" showLitChar '\r' = showString "\\r" showLitChar '\t' = showString "\\t" showLitChar '\v' = showString "\\v" showLitChar '\SO' = protectEsc (== 'H') (showString "\\SO") showLitChar c = showString ('\\' : asciiTab!c) protectEsc p f = f . cont where cont s@(c:_) | p c = "\\&" ++ s cont s = s asciiTab = listArray ('\NUL', ' ') ["NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US", "SP"] lexLitChar :: ReadS String lexLitChar ('\\':s) = map (prefix '\\') (lexEsc s) where lexEsc (c:s) | c `elem` "abfnrtv\\\"'" = [([c],s)] lexEsc ('^':c:s) | c >= '@' && c <= '_' = [(['^',c],s)] -- Numeric escapes lexEsc ('o':s) = [prefix 'o' (span isOctDigit s)] lexEsc ('x':s) = [prefix 'x' (span isHexDigit s)] lexEsc s@(d:_) | isDigit d = [span isDigit s] -- Very crude approximation to \XYZ. lexEsc s@(c:_) | isUpper c = [span isCharName s] lexEsc _ = [] isCharName c = isUpper c || isDigit c prefix c (t,s) = (c:t, s) lexLitChar (c:s) = [([c],s)] lexLitChar "" = [] haskell98-report-20080907/libraries/code/Array.hs0000644000175000017500000000633111345221572020743 0ustar marcotmarcotmodule 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 // new_ivs = array (bounds a) (old_ivs ++ new_ivs) where old_ivs = [(i,a!i) | i <- indices a, i `notElem` new_is] new_is = [i | (i,_) <- new_ivs] 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 > arrPrec) ( showString "array " . showsPrec (arrPrec+1) (bounds a) . showChar ' ' . showsPrec (arrPrec+1) (assocs a) ) instance (Ix a, Read a, Read b) => Read (Array a b) where readsPrec p = readParen (p > arrPrec) (\r -> [ (array b as, u) | ("array",s) <- lex r, (b,t) <- readsPrec (arrPrec+1) s, (as,u) <- readsPrec (arrPrec+1) t ]) -- Precedence of the 'array' function is that of application itself arrPrec = 10 haskell98-report-20080907/libraries/index.html0000644000175000017500000000661711345221573020424 0ustar marcotmarcot The Haskell 98 Library Report
Haskell 98 Libraries

Standard Libraries for Haskell 98

Revised: Sept 2002


Table of Contents


Simon Peyton Jones [editor], Microsoft Research, Cambridge
John Hughes [editor], Chalmers University of Technology
Lennart Augustsson, Sandburst Corporation
Dave Barton, Intermetrics
Brian Boutel, Victoria University of Wellington
Warren Burton, Simon Fraser University
Joseph Fasel, Los Alamos National Laboratory
Kevin Hammond, University of St. Andrews
Ralf Hinze, University of Bonn
Paul Hudak, Yale University
Thomas Johnsson, Chalmers University of Technology
Mark Jones, Oregon Graduate Institute
John Launchbury, Oregon Graduate Institute
Erik Meijer, Microsoft Corporation
John Peterson, Yale University
Alastair Reid, University of Utah
Colin Runciman, York University
Philip Wadler, Avaya Labs

Copyright (c) Simon Peyton Jones and John Hughes.
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 entirity, 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 a definition of the language Haskell 98.

The master version of the Haskell Library Report is at haskell.org. Any corrections or changes in the report are found there. haskell98-report-20080907/libraries/char.verb0000644000175000017500000000633611345221572020221 0ustar marcotmarcot%**The Haskell 98 Library Report: Character Utilities %**~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 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{code/Char} %**~footer haskell98-report-20080907/libraries/directory.verb0000644000175000017500000001670511345221572021311 0ustar marcotmarcot%**The Haskell 98 Library Report: Directory functions %**~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{headers/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}. @get(set)Permissions@, @doesFile(Directory)Exist@, and @getModificationTime@ may fail with: @isPermissionError@ if the user is not permitted to access the appropriate information; or @isDoesNotExistError@ if the file/directory does not exist. The @setPermissions@ computation may also fail with: @isPermissionError@ if the user is not permitted to change the permission for the specified file or directory; or @isDoesNotExistError@ if the file/directory does not exist. % Duplicates the first case above, and would require % extensive consistency checking throughout. KH % The @doesFileExist@ and @doesDirectoryExist@ computations % may also fail with @isPermissionError@ if some part of the path % to the file/directory cannot be searched. %**~footer haskell98-report-20080907/libraries/h98-libs.ppt0000644000175000017500000006500011345221572020501 0ustar marcotmarcotÐÏࡱá>þÿ þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿ"þÿÿÿ #þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿþÿÿÿ%&'()*+,-./0123þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot Entryÿÿÿÿÿÿÿÿd›Oφꪹ)èàDõí¾Picturesÿÿÿÿÿÿÿÿ PowerPoint Document(ÿÿÿÿÿÿÿÿ$†SummaryInformation(ÿÿÿÿ0  !"#$%&'()*+þÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿjklmnopqrsþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ F𺠘îNû§²ÝaR­A€ ÇGÿØÿàJFIFKKÿãMSO Palette àÂ’ãͨäÉæÒ±çѪéΡé×·êÕ¯ëÒ£ëÓ­ë×±ìØ·ìÚ¹íݾîÖ«îÚ¸îܸïÙ¯ïݹïßÀñݵñß¾ñâÀñãÆò߸òáÀôã¾ôäÅôçÊõçÄöêËøîÐÛ¹…ÝÂ—ÝÆ Þ¿ŒÞɧàÈ áÆšáÌ«âʦâÌ¥âέãÉäÃ‰äÆ˜äΧäΫäаåÊŸåÌ åΣåϬåЫåÒ±åÓ³æÆŒæÉ”æÑ«æÓ²çÊçͤçϨçЩçÓ­èÌŸè͘èΤèФèЪèѪèÒ°èÓ©èÔ°èÔ´èÕ±èÖµèÖ¸è×·éÉ’éΠéϧéÔ³éÕ®éÕ±é×±éÚ¹êПêÐ¥êÑ«êÒ¥êÒ«êÓ¥êÓ®êÔ¬êÕ©êÕ²êÖ¶ê×¶êØ²êØ·ëΖëÓ¬ëÔ²ëײë×·ëÙ¶ëÙ¹ëÚ¸ëÚ¹ëÚ»ëÜ¿ìÒ¦ìÔ«ìÕªìÕ®ìÕ±ìÖµì×­ì×²ìØ¯ìÙ²ìÚ¶ìÚ»ìÛ·ìÜ»ìÝ¿íÑíÔ¦íÕ¯íØ·íÛ¼íܸíܺíܾîÓŸîÖªîÖ®î׫î×°îÙ¯îÙ²îÙ¶îÚ¶îÚºîÛ·îÜ´îÜ»îܾîÝ·îÝ»îÞÁîß¾îßÂîàÂïÖ ïÖ§ïÙªïÙ±ïÚ²ïÚ·ïÜ´ïܾïÝ·ïݾïÞ¸ïÞ»ïߺïß½ïßÁïàÁðÚ®ðÛ¸ðܵðܸðݽðÞ¾ðà½ðàÀðâÀðâÆñܲñÞºñ߸ñߺñß½ñßÀñßÁñàºñà¾ñáÀñáÃñâÅñã½ñãÀñãÂñäÆñäÇòÚ¨òÜ­òܹòݵòß½òâ½òâÁòâÅòãÂòäÇòåÆòæËóß²óß¶óà¸óàºóà¾óáÂóâÁóãÄóäÇóåÄóåÇóæÆóæÈóèËôâ¸ôâ¾ôãÁôä½ôäÁôæÂôçÄôçËôêÎõãÄõåÆõæÈõéÈõéËõêÎõìÐöæÀöæÅöçÂöçÉöèÆöèÊöìÌöîÑ÷éÅ÷éÉ÷êÍøìÊøìÐùîÐùðÓúó×ÿÛC   ")$+*($''-2@7-0=0''8L9=CEHIH+6OUNFT@GHEÿÛC !!E.'.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEÿÀ€€"ÿÄÿÄ0!1AQ"aq¡2‘±#ÁÑáCRrðñÿÄÿÄ1AÿÚ ?ô%÷~êìc¦¨ß“ŒFD){|`­Ôô‡Œàt™U¶þ)Ãþ%lŽn¼`÷ *ûc’RÚœ"lBºwo|=ßnëx&ÉIŽ`»~‡s-“¼—šâÞ®ORvÊ´ŸoÒŽûùñŠ®y/ßž1¼™húdz×OyU/&9÷srjð2+›¿œÂ޽ÛãÆEb*õ&ÿ£+îê¯LÓçYÃíO8cêTTðòåF‰¾Oïì¾xÃ/SÝÃ\ MT«ã¶.Ae¯|HCÖ<ïš§ƒj Ë}ñ£Kk¯.±š ýøÌFR×`¥^˜öé=´™êÚ×(`’óßjíD/Ó Úïï“dƯMÞ]ÕÆ$¶CIù±è¾|àiw)x¬Y;#)Úíãñ™Vé—vl¼¶ƒ{‰ã2çEüxÆ”©ê<^Tmvúb‘©[ãxCƒ»ñ ÊÂ*Š?ÞX‰J1bvyÆ=9^¥+ïxI,d[¼7öÉ?òÈ5ûoº`eªÍb&ï^«kë–ŒÙdKþ~¹®ÑŽ«¿ÇÓ­:»oÅb3÷6P4k'¥.Š©5\¸gûßúáýD$=µ€c-Q]Ç(XÇG|ëˆXê𨧶¸Í/PõzÀ4î÷‡Ò )ãÿ˜:¯GÎÎØÌ“÷5z£_VA+SÅ`½|½°J•on¼ëNKúwÌú«ÂÔŒ¸är½U¨xíœð’Å­v/¾S®˜Ä7Å™PzäPÕ>9ÿœÀþûœ듺5¼4 ’À”›«æ“q²2.®œn†õ¯—xç¦~ï—Rƒ( &%h¯Û›¦R—ÆRP€WM&‡ "?´ûâ9 î¥MÇí‘u߯3q85Û F]´|o`¬ûëkÎûíjÞ^øº«~ÙE:þq':X_ç(¿8 m眈”o—¾hv-SÓ„Cç·Æ#­™ õ:MvÊú^§êDIiÿý?" ddÏÿÿïÿÿÿÿÿÿ£|ÿý?" ddMÏÿÿïÿÿÿÿÿÿ € ¨h €" Ï € k7€»ÒŸ £nÿý?" dd@ÿÿïÿÿÿÿÿÿ   @@``€€P£R  h Ï 7 Ÿ`£ p£>  €£>  Ãð»ððSð( ðõõõõõõõõõõõõõõõõ ððð ð ã ðT€4|–€‚K@ƒ–€„K@‡¿ƒ¿Àÿ ð>Ç“ ±ðà  ðTŸ¨ Click to edit Master title style¢!ª !ð4 ð Ó ðN€Ô{–€‚K@ƒ–€„K@¿ƒ¿Àÿ ðÈÇ“ fðà  ðžŸ¨RClick to edit Master text styles Second level Third level Fourth level Fifth level¢!    ª Sðñ ð Ó ðN€t{–€‚K@ƒ–€„K@¿ƒ¿Àÿ ðuÇï¤ðà  ð[Ÿ¨*¡ø¦ñÏhhÏÏ77ŸŸðó ð Ó ðN€{–€‚K@ƒ–€„K@¿ƒ¿Àÿ ðu‰Ñ¤ðà   ð]Ÿ¨*¡ú¦ñÏhhÏÏ77ŸŸðó ð Ó ðN€´z–€‚K@ƒ–€„K@¿ƒ¿Àÿ ðuk“ ¤ðà  ð]Ÿ¨*¡Ø¦ñÏhhÏÏ77ŸŸðH ð ƒ ð0ƒ“éI@”ÑÕ¿ÿ ?ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²² º,Blank Presentation.potî6ï€ æðÞ ððvð( ð   ðð>" ð C ðŽ€x–€‚K@ƒ–€„K@…‡¿€ÿÿ̆A‡Á¿Àÿ¨)¨)?¿Stationeryð`0ð M ð€Ÿ¨ Haskell 98¡"  ,ª¦ñÏhhÏÏ77ŸŸðH ð ƒ ð0ƒ“éI@”ÑÕ¿ÿ ?ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²²r0#Ä õpþÿÕÍÕœ.“—+,ù®DÕÍÕœ.“—+,ù®Àˆ ¬´¼Ä Ì ÔÜ äìôü  ^äCustom st†è Times New Roman Arial BlackBlank Presentation.potNo Slide Title  Fonts Usedþÿà…ŸòùOh«‘+'³Ù0 hpˆ¤ð  8 D P\däNo Slide TitleSimon Peyton JonesCC:\Program Files\Microsoft Office\Templates\Blank Presentation.potSimon Peyton Jonesc3moMicrosoft PowerPointoso@œf· @>à¾@ †õí¾G”ÿÿÿÿo§ B ‘ &ÿÿÿÿºš &ÿÿÿÿ&#ÿÿÿÿTNPPpð0D z & TNPPô &ÿÿÿÿ&TNPP   šº ÿÿÿ ‘ A Ì šº( à€€€€€€€€€ÀÀÀÀÜÀðʦ """)))UUUMMMBBB999€|ÿPPÿ“ÖÿìÌÆÖïÖçç©­3f™Ì3333f3™3Ì3ÿff3fff™fÌfÿ™™3™f™™™Ì™ÿÌÌ3ÌfÌ™ÌÌÌÿÿfÿ™ÿÌ3333f3™3Ì3ÿ3333333f33™33Ì33ÿ3f3f33ff3f™3fÌ3fÿ3™3™33™f3™™3™Ì3™ÿ3Ì3Ì33Ìf3Ì™3ÌÌ3Ìÿ3ÿ33ÿf3ÿ™3ÿÌ3ÿÿff3fff™fÌfÿf3f33f3ff3™f3Ìf3ÿffff3fffff™ffÌf™f™3f™ff™™f™Ìf™ÿfÌfÌ3fÌ™fÌÌfÌÿfÿfÿ3fÿ™fÿÌÌÿÿÌ™™™3™™™™Ì™™33™f™3Ì™ÿ™f™f3™3f™f™™fÌ™3ÿ™™3™™f™™™™™Ì™™ÿ™Ì™Ì3fÌf™Ì™™ÌÌ™Ìÿ™ÿ™ÿ3™Ìf™ÿ™™ÿÌ™ÿÿÌ™3ÌfÌ™ÌÌ™3Ì33Ì3fÌ3™Ì3ÌÌ3ÿÌfÌf3™ffÌf™ÌfÌ™fÿ̙̙3Ì™fÌ™™Ì™ÌÌ™ÿÌÌÌÌ3ÌÌfÌÌ™ÌÌÌÌÌÿÌÿÌÿ3™ÿfÌÿ™ÌÿÌÌÿÿÌ3ÿfÿ™Ì3ÿ33ÿ3fÿ3™ÿ3Ìÿ3ÿÿfÿf3Ìffÿf™ÿfÌÌfÿÿ™ÿ™3ÿ™fÿ™™ÿ™Ìÿ™ÿÿÌÿÌ3ÿÌfÿÌ™ÿÌÌÿÌÿÿÿ3Ìÿfÿÿ™ÿÿÌffÿfÿffÿÿÿffÿfÿÿÿf!¥___www†††–––ËË˲²²×××ÝÝÝãããêêêñññøøøðûÿ¤  €€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøøøøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼šÃ¼ ¼½Ÿ¼ ¼Ã½™Ã½Ã¼ššÂš¼šÂš½ ¼ ½Ã½½Âš¼šÃ¼ ¼½Ÿ¼ ¼Ã½™Ã½Ã¼ššÂš¼šÂš½ ¼ ½Ã½½Âš¼šÃ¼ ¼½Ÿ¼ ¼Ã½™Ã½Ã¼ššÂš¼šÂš½ ¼ ½Ã½½Âš¼šÃ¼ ¼½Ÿ¼ ¼Ã½™Ã½Ã¼ššÂøøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýšýÃý½Ã½Ã™Ã½š½Ã¼½™Ãš¼ ¼Ãš¼Ã½™ÃÚýšýÃý½Ã½Ã™Ã½š½Ã¼½™Ãš¼ ¼Ãš¼Ã½™ÃÚýšýÃý½Ã½Ã™Ã½š½Ã¼½™Ãš¼ ¼Ãš¼Ã½™ÃÚýšýÃý½Ã½Ã™Ã½š½Ã¼½™øøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿš¼ ½™½Âš¼ ¼š¼Ã½™ÃšüšÙ½Ÿ½šÃš¼ÃšÂš½¼š¼ ½™½Âš¼ ¼š¼Ã½™ÃšüšÙ½Ÿ½šÃš¼ÃšÂš½¼š¼ ½™½Âš¼ ¼š¼Ã½™ÃšüšÙ½Ÿ½šÃš¼ÃšÂš½¼š¼ ½™½Âš¼ ¼š¼Ã½™ÃšüšÙ½øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½Ã½™Ã™½½Ã½Ã½Ã½½Ã½Ã™Ã½Ã™½Ã½š½Â½™Ãš¼šÂ½ ½Ã½™Ã™½½Ã½Ã½Ã½½Ã½Ã™Ã½Ã™½Ã½š½Â½™Ãš¼šÂ½ ½Ã½™Ã™½½Ã½Ã½Ã½½Ã½Ã™Ã½Ã™½Ã½š½Â½™Ãš¼šÂ½ ½Ã½™Ã™½½Ã½Ã½Ã½½Ã½Ã™Ã½Ã™½Ã½øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ¼ ½ ¼ ¼½Ã¼ Ù¼½½Ÿ½Ã¼ ½ÂššÃ™½ ½Ãš½ ¼ ½ ¼ ¼½Ã¼ Ù¼½½Ÿ½Ã¼ ½ÂššÃ™½ ½Ãš½ ¼ ½ ¼ ¼½Ã¼ Ù¼½½Ÿ½Ã¼ ½ÂššÃ™½ ½Ãš½ ¼ ½ ¼ ¼½Ã¼ Ù¼½½Ÿ½Ã¼ ½øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½½Ãü½Ã½Âš½¼š¼ÃšÃ™ ½™½ ¼Ãš¼ ½¼šÂ½½™Ã½½Ãü½Ã½Âš½¼š¼ÃšÃ™ ½™½ ¼Ãš¼ ½¼šÂ½½™Ã½½Ãü½Ã½Âš½¼š¼ÃšÃ™ ½™½ ¼Ãš¼ ½¼šÂ½½™Ã½½Ãü½Ã½Âš½¼š¼ÃšÃ™ ½™½ ¼Ãøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ™Ã¼ ½Ÿ½Ã¼šÃ™½™½½š¼½ ½Ã¼ Ã¼šÃ™½™½™½™š¼ ½Ÿ¼ ½½™ÃüšÃ™½™½™½½½ ½½¼ Ã¼šÂ™½™½™½™½™½šøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýýšÃý ¼š™½¼ ½Â½½ššÃ½ÃÃý ½š™Ã™½Â½¼šÃÃýšÃ™½™Ã™š¼Â ¼ššÃÃÃÃý™½ ½š™Ã™½™š¼ øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼šÃ™ÃšÃ¼š½š¼šÃšÃ½Ã™½¼¼šÃšÃ¼š½š¼¼Ãš™šÃ½Ÿ™½ Ã½Ÿ½š¼šÃšÃ¼š½ššš™½Ÿ½½šÃ¼Ÿ½šÃšÃ¼š½Ÿ½¼Ãš™šÃ½Ÿ½ÃøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÃü½½™½šÂšš¼š¼¼š½šÃ¼ÃÃ¼Âšš™šš¼š¼š½Ã½Ÿ½½¼Ãý™½šÂÂšÂ¼š™½¼š½¼šÃ½½¼¼Âš½Âšš¼š¼š™½¼šøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿš¼šŸ¼ ½Ÿ½Ã™ ¼ ½ÂýšŸš¼š ½Ãš¼¼™ ½ Â ¼Ã½Ÿ½½š¼¼ ½Ÿ½šš ½  ½Âš½š ½Ã™¼šš¼™ ½ ¼š¼ ½øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÂšÃ½š½™½™ ½™š¼š¼š¼š½™šÃšÃ½½™ ½šš¼š¼¼š½½½™šÃ½Âšš½™½™¼ š¼š š¼ ½™š½Ã½½™š¼šš¼š¼½ ¼š¼øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½™½Ÿ½Ÿ½™½Ÿ™š¼½™šÃ™½šÂ½Ÿ½Ÿš¼šŸ½™š½™½Ÿ½Ÿ½™½Ÿ™š™½™šÃŸ½Ÿ™½™š½™½Ÿ½™½Ÿ½™š™½™šÃ™½šÂ½Ÿ½Ÿš¼šŸ½™½™š½™½Ÿ½Ÿ½™½Ÿ½™š¼š™½™šÃ™½šÂ½øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿšš¼š¼ ½¼š¼š ¼š™½ ¼šš¼š½™Ãš½™š½ÂšÂš¼š¼ ½¼š¼½ ¼š™½š¼š½™™š™š½Âš¼š¼ ½½š™½ ¼š™½ ¼šš¼š½™Ãš½™š™š½Âš¼š¼ ½¼š½š¼š™½ ¼š™½ ¼ššøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ™½™ÃšÃ½™ÃšÂ½Ÿ½ ½Ÿ½š¼½ ¼šÂš¼šŸ½™½Ÿš½Ÿ½½™½™ÃšÃ½™ÃšÂ½Ÿ½ ½Ÿ½š¼½ ¼šÂš¼šŸ½™½Ÿš½Ÿ½½™½™ÃšÃ½™ÃšÂ½Ÿ½ ½Ÿ½š¼½ ¼šÂš¼šŸ½™½Ÿš½Ÿ½½™½™ÃšÃ½™ÃšÂ½Ÿ½ ½Ÿ½š¼½ ¼šÂšøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÂšš¼š¼™Ãš¼š™½™½™½šÂšÃ™½™š½Ÿš¼½Ÿ½½™½ššÂšš¼š¼™Ãš¼š™½™½™½šÂšÃ™½™š½Ÿš¼½Ÿ½½™½ššÂšš¼š¼™Ãš¼š™½™½™½šÂšÃ™½™š½Ÿš¼½Ÿ½½™½ššÂšš¼š¼™Ãš¼š™½™½™½šÂšÃ™½™š½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿš½ÂšÃšÃ½Ÿ½™ÃšÃš¼š¼š½™½Ÿ½™½™½ ½šÂšÃ™½Â½š½ÂšÃšÃ½Ÿ½™ÃšÃš¼š¼š½™½Ÿ½™½™½ ½šÂšÃ™½Â½š½ÂšÃšÃ½Ÿ½™ÃšÃš¼š¼š½™½Ÿ½™½™½ ½šÂšÃ™½Â½š½ÂšÃšÃ½Ÿ½™ÃšÃš¼š¼š½™½Ÿ½™ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ½š¼š¼ ½Ã½¼š½¼š™½™™¼š™½™½š¼½™Ã½Ãšš¼ ½š¼š¼ ½Ã½¼š½¼š™½™™¼š™½™½š¼½™Ã½Ãšš¼ ½š¼š¼ ½Ã½¼š½¼š™½™™¼š™½™½š¼½™Ã½Ãšš¼ ½š¼š¼ ½Ã½¼š½¼š™½™™¼š™½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿú-ü-&TNPP &ÿÿÿÿš¼š½ ½Ã™¼™Ÿ¼ ¼ ½™½Ÿ½™½š½Ÿøÿÿÿÿÿÿÿ™½š½šÂš½™ÃšÃ¼š¼šÂš½™½™½™½™½Ÿš½Â𙽙½š¼ ½Ÿ½š™š½™š½šÂš½™ÃšÃ¼š¼ ½½š¼šÂš½ššš½™½Âš™½™½š¼ ½Ÿ™š½½™½š½šÂÃ¼š¼ ½½š¼šÂš½šššÂš™øÿÿÿÿÿÿÿšÂ™™™½™Ãš¼š¼ ½šÂšŸ½™½š¼ ¼Ã¼š½Ã¼ ¼Ãš¼š½™™š½™šÃ™¼š™½™½Âš¼ ¼ ÃšÂ™™™½™Ãš¼š¼ ½šÂšŸ½™½š¼ ¼Ã¼š½Ã¼ ¼Ãš¼š½™™š½™šÃ™¼š™½™½Âš¼ ¼ ÃšÂ™™™½™Ãš¼š¼ ½šÂšŸ½™½š¼ ¼Ã¼š½Ãøÿÿÿÿÿÿÿ™½š½š¼ ¼š¼ ™½Ã™½™½Ÿ½šÂš¼šš½ ¼š½š™Ã™Ã™½š¼šŸ½™½šÃ¼šÃš½Ÿ½™½ ½½™½š½š¼ ¼š¼ ™½Ã™½™½Ÿ½šÂš¼šš½ ¼š½š™Ã™Ã™½š¼šŸ½™½šÃ¼šÃš½Ÿ½™½ ½½™½š½š¼ ¼š¼ ™½Ã™½™½Ÿ½šÂš¼šš½ ¼ÿÿÿÿÿÿÿÿÃ™Ã™Ã½š½Ÿ½Ã½ ¼Ãš¼½šÂ½šÃšÂš™Ã™½Ÿ½Ã¼š½™½Ÿ½š¼š½Ÿ½ÂšüٽÙ½™šÃ™Ã™Ã½š½Ÿ½Ã½ ¼Ãš¼½šÂ½šÃšÂš™Ã™½Ÿ½Ã¼š½™½Ÿ½š¼š½Ÿ½ÂšüٽÙ½™šÃ™Ã™Ã½š½Ÿ½Ã½ ¼Ãš¼½šÂ½šÃšÂš™Ã™½ÿÿÿÿÿÿÿÿÿ¼š½šÃšÂ½š½™Ãš¼ ½™Ã½ ¼š¼š™½™½™š¼™š½Ÿ½™š½Ÿš¼ ½¼š½Ÿ½šÃ½ ½™Ã™½¼š¼š½šÃšÂ½š½™Ãš¼ ½™Ã½ ¼š¼š™½™½™š¼™š½Ÿ½™š½Ÿš¼ ½¼š½Ÿ½šÃ½ ½™Ã™½¼š¼š½šÃšÂ½š½™Ãš¼ ½™Ã½ ¼š¼š™½™½™ÿÿÿÿÿÿÿÿÿÙý™¼šŸ¼Ãýý½™Ãš¼½ ½™½™½™š¼™š¼š™¼šÂš¼š¼š¼š ¼š½™Âš¼½Ÿ½š¼ ÃšÃ™Ã½™¼šŸ¼Ãýý½™Ãš¼½ ½™½™½™š¼™š¼š™¼šÂš¼š¼š¼š ¼š½™Âš¼½Ÿ½š¼ ÃšÃ™Ã½™¼šŸ¼Ãýý½™Ãš¼½ ½™½™½™šÿÿÿÿÿÿÿÿÿÿÿš½½ ½½šš™Ã™Ã™½™Ã™¼š¼š¼š½™½™™¼š½™½½š¼šÂš¼¼š¼Ã½š¼ ½Ã½¼ ½™½™½š½½ ½½šš™Ã™Ã™½™Ã™¼š¼š¼š½™½™™¼š½™½½š¼šÂš¼¼š¼Ã½š¼ ½Ã½¼ ½™½™½š½½ ½½šš™Ã™Ã™½™Ã™¼š¼š¼šÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿú-ü-&TNPP &ÿÿÿÿDocumentSummaryInformation8ÿÿÿÿÿÿÿÿÿÿÿÿiœCurrent Userÿÿÿÿÿÿÿÿÿÿÿÿ,2ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿDesign Template Slide Titles˜ 6> _PID_GUIDäAN{93742906-809D-11D2-9B95-00A0244D177F}ö*_À‘ãôSimon Peyton Jonesèé(Z ³à€ ò</È 0ÒÕ˜·DTimes New RomanÈ·È·Ô³…Þ0ø³ø³ ß0·DArial BlackmanÈ·È·Ô³…Þ0ø³ø³ ß0"©  @£nÿý?" dd@ÿÿïÿÿÿÿÿÿ  @@``€€ ¨ð ð ð,Rð$˜îNû§²ÝaR­A€ ÇGÿ (c ð$ƒ¿Àÿ@ñ÷ðó€Ð‹ÿ úgþý4dddd´ ß0ü³þ²öÿÿØ÷ÿÿpû[pû@?Ù Ú%ðóêø™ ï `ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²²`ð ÿÿÿÿÿÿÿ™ÿÿÿ–––`ð ÿÿÌff3€€3™3€3ÌÿÌf`ð ÿÿÿ333ÝÝÝ€€€MMMêêê`ð ÿÿÿ€€€ÿÌfÿÌÌÀÀÀ`ð ÿÿÿ€€€ÀÀÀfÿÿ™`ð ÿÿÿ€€€3™ÿ™ÿÌÌ̲²²£>ÿý?" ddÏÿÿïÿÿÿÿÿÿ£|ÿý?" ddMÏÿÿïÿÿÿÿÿÿ € ¨h €" Ï € k7€»ÒŸ £nÿý?" dd@ÿÿïÿÿÿÿÿÿ   @@``€€P£R  h Ï 7 Ÿ`£ p£>  €£>  Ãð»ððSð( ðõõõõõõõõõõõõõõõõ ððð ð ã ðT€4|–€‚K@ƒ–€„K@‡¿ƒ¿Àÿ ð>Ç“ ±ðà  ðTŸ¨ Click to edit Master title style¢!ª !ð4 ð Ó ðN€Ô{–€‚K@ƒ–€„K@¿ƒ¿Àÿ ðÈÇ“ fðà  ðžŸ¨RClick to edit Master text styles Second level Third level Fourth level Fifth level¢!    ª Sðñ ð Ó ðN€t{–€‚K@ƒ–€„K@¿ƒ¿Àÿ ðuÇï¤ðà  ð[Ÿ¨*¡ø¦ñÏhhÏÏ77ŸŸðó ð Ó ðN€{–€‚K@ƒ–€„K@¿ƒ¿Àÿ ðu‰Ñ¤ðà   ð]Ÿ¨*¡ú¦ñÏhhÏÏ77ŸŸðó ð Ó ðN€´z–€‚K@ƒ–€„K@¿ƒ¿Àÿ ðuk“ ¤ðà  ð]Ÿ¨*¡Ø¦ñÏhhÏÏ77ŸŸðH ð ƒ ð0ƒ“éI@”ÑÕ¿ÿ ?ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²² º,Blank Presentation.potî6ï€ æðÞ ððvð( ð   ðð>" ð C ðŽ€x–€‚K@ƒ–€„K@…‡¿€ÿÿ̆A‡Á¿Àÿ¨)¨)?¿Stationeryð`0ð M ð€Ÿ¨ Haskell 98¡"  ,ª¦ñÏhhÏÏ77ŸŸðH ð ƒ ð0ƒ“éI@”ÑÕ¿ÿ ?ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²²r0#Ä õpèé(3³à€ ò</È 0ÒÕ˜·DTimes New Roman¬·¬·¸³…Þ0ܳܳ ß0·DArial Blackman¬·¬·¸³…Þ0ܳܳ ß0"©  @£nÿý?" dd@ÿÿïÿÿÿÿÿÿ  @@``€€ ¨ð ð ð,Rð$˜îNû§²ÝaR­A€ ÇGÿ (c ð$ƒ¿Àÿ@ñ÷ðó€Ð‹ÿ úgþý4ddddè³ ß0à³þšùÿÿØ÷ÿÿpû[pû+?Ù Ú%ðóêø™ ï `ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²²`ð ÿÿÿÿÿÿÿ™ÿÿÿ–––`ð ÿÿÌff3€€3™3€3ÌÿÌf`ð ÿÿÿ333ÝÝÝ€€€MMMêêê`ð ÿÿÿ€€€ÿÌfÿÌÌÀÀÀ`ð ÿÿÿ€€€ÀÀÀfÿÿ™`ð ÿÿÿ€€€3™ÿ™ÿÌÌ̲²²£>ÿý?" ddÏÿÿïÿÿÿÿÿÿ£|ÿý?" ddMÏÿÿïÿÿÿÿÿÿ € ¨h €" Ï € k7€»ÒŸ £nÿý?" dd@ÿÿïÿÿÿÿÿÿ   @@``€€P£R  h Ï 7 Ÿ`£ p£>  €£>  Ãð»ððSð( ðõõõõõõõõõõõõõõõõ ððð ð ã ðT€4|–€‚K@ƒ–€„K@‡¿ƒ¿Àÿ ð>7ü±ðà  ðTŸ¨ Click to edit Master title style¢!ª !ð4 ð Ó ðN€Ô{–€‚K@ƒ–€„K@¿ƒ¿Àÿ ðÈ7üfðà  ðžŸ¨RClick to edit Master text styles Second level Third level Fourth level Fifth level¢!    ª Sðñ ð Ó ðN€t{–€‚K@ƒ–€„K@¿ƒ¿Àÿ ðu7–¤ðà  ð[Ÿ¨*¡ø¦ñÏhhÏÏ77ŸŸðó ð Ó ðN€{–€‚K@ƒ–€„K@¿ƒ¿Àÿ ðuˆ« ¤ðà   ð]Ÿ¨*¡ú¦ñÏhhÏÏ77ŸŸðó ð Ó ðN€´z–€‚K@ƒ–€„K@¿ƒ¿Àÿ ðu ü¤ðà  ð]Ÿ¨*¡Ø¦ñÏhhÏÏ77ŸŸðH ð ƒ ð0ƒ“d”ÑÕ¿ÿ ?ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²² º,Blank Presentation.potî@ï€ ððè ðð€ð( ð   ððH" ð C ðŽ€x–€‚K@ƒ–€„K@…‡¿€ÿÿ̆A‡Á¿Àÿ¨)¨)?¿Stationeryð` ^M ðŠŸ¨Haskell 98 Libraries¡"$ª ¦ñÏhhÏÏ77ŸŸðH ð ƒ ð0ƒ“d”ÑÕ¿ÿ ?ð ÿÿÿ€€€Ì™33ÌÌÌÿ²²²r0>aõpJhaskell98-report-20080907/libraries/Makefile0000644000175000017500000001227311345221572020061 0ustar marcotmarcot# Makefile for the Haskell Library Report # read the README file before you start! # # Begin by saying # touch library.idx default: library.ps.gz 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 # EXPAND = c:/cygwin/bin/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 RELEASE_DIR = ../haskell98-revised JFP_DIR = ../jfp-release 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 release: library.ps html gzip < library.ps > $(RELEASE_DIR)/library.ps.gz cp -r haskell98-library-html $(RELEASE_DIR) tar cvf - haskell98-library-html | gzip > $(RELEASE_DIR)/haskell98-library-html.tar.gz publish-pdf: library.pdf gzip < library.pdf > y:Haskell/haskell98-library/library.pdf.gz jfp: ${PARTS} ${CODE} ${HEADERS} index-intro.tex -mkdir $(JFP_DIR) -mkdir $(JFP_DIR)/code -mkdir $(JFP_DIR)/headers for n in ${PARTS} ${CODE} ${HEADERS}; do \ ../tools/subsection < $$n > $(JFP_DIR)/$$n ; done ######################################### # Suffix rules ######################################### .SUFFIXES: .hs .verb .tex .dvi .gz .ps .verb.tex: $(EXPAND) < $< | $(VERBATIM) >$@ .hs.verb: $(EXPAND) < $< | $(SPLITPGM) >$@ .hs.tex: $(EXPAND) < $< | $(SPLITPGM) | $(VERBATIM) >$@ .tex.dvi: $(LATEX) $< haskell98-report-20080907/libraries/cputime.verb0000644000175000017500000000076711345221572020754 0ustar marcotmarcot%**The Haskell 98 Library Report: CPU Time %**~header \section{CPU Time} \label{cputime} \index{CPU time} \index{execution time} \outline { \inputHS{headers/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 haskell98-report-20080907/libraries/locale.verb0000644000175000017500000000064611345221573020542 0ustar marcotmarcot%**The Haskell 98 Library Report: Locale %**~header \section{Locale} \label{locale} \index{locale} \outline { \inputHS{headers/Locale} } The @Locale@ library provides the ability to adapt to local conventions. At present, it supports only time and date information as used by @calendarTimeToString@ from the @Time@ library. \clearpage \subsection{Library {\tt Locale}} \inputHS{code/Locale} %**~footer haskell98-report-20080907/libraries/html.config0000644000175000017500000000225411345221573020553 0ustar marcotmarcotaux=library.aux htmldir=haskell98-library-html/ refs=librefs files=introduction.verb files=ratio.verb files=complex.verb files=numeric.verb files=ix.verb files=array.verb files=list.verb files=maybe.verb files=char.verb files=monad.verb files=io.verb files=directory.verb files=system.verb files=time.verb files=locale.verb files=cputime.verb files=random.verb #files=bit.verb #files=nat.verb #files=signed.verb index=haskell98-library-html/libindex.html style=article ~top=top ~style= ~id=The Haskell 98 Library Report
~back=back ~nxt=next ~contents=contents ~foot=
Sept 2002 ~footer=


~id~top | ~back | ~nxt | ~contents ~foot ~sfooter=
~id~top | back | ~nxt | ~contents ~foot ~efooter=
~id~top | ~back | next | ~contents ~foot ~header=~style ~id ~top | ~back | ~nxt | ~contents

~sheader=~style ~id ~top | back | ~nxt | ~contents

~eheader=~style ~id ~top | ~back | next | ~contents

~indexHeader=Haskell 98 Library Index~style ~id~top

Haskell 98 Library Report: Index

haskell98-report-20080907/libraries/time.verb0000644000175000017500000000535011345221573020236 0ustar marcotmarcot%**The Haskell 98 Library Report: Dates and Times %**~header \section{Dates and Times} \label{time} \index{time} \index{time of day}\index{clock time} %% Note: HBC has Leap year calculations too. %% My feeling is that these are unnecessary given the much stronger %% ability here to find the differences between dates. \outline { \inputHS{headers/Time} } \outline{ \inputHS{headers/Time1} } The @Time@ library provides standard functionality for clock times, including timezone information. It follows RFC~1129 in its use of Coordinated Universal Time (UTC). @ClockTime@ is an abstract type, used for the system's internal clock time. Clock times may be compared directly or converted to a calendar time @CalendarTime@ for I/O or other manipulations. @CalendarTime@ is a user-readable and manipulable representation of the internal @ClockTime@ type. The numeric fields have the following ranges. \outline{ \begin{tabbing} \ignorehtml{ \ \ \ \=ctpicosec\ \ \ \ \=-maxInt\ \=\ldots\ \=$(10^{12})-1$\ \ \ \ \ \=\kill} \>\underline{Value}\>\>\underline{Range}\>\>\underline{Comments} \\ \\ \>ctYear\>\>-maxInt\'$\ldots$\>maxInt\>Pre-Gregorian dates are inaccurate \\ \>ctDay\>\>1\'$\ldots$\>31 \\ \>ctHour\>\>0\'$\ldots$\>23\\ \>ctMin\>\>0\'$\ldots$\>59\\ \>ctSec\>\>0\'$\ldots$\>61\>Allows for two Leap Seconds\\ \>ctPicosec\>\>0\'$\ldots$\>$(10^{12})-1$ \\ \>ctYDay\>\>0\'$\ldots$\>365\>364 in non-Leap years \\ \>ctTZ\>\>-89999\'$\ldots$\>89999\>Variation from UTC in seconds \end{tabbing} } The "ctTZName" field is the name of the time zone. The "ctIsDST" field is @True@ if Daylight Savings Time would be in effect, and @False@ otherwise. The @TimeDiff@ type records the difference between two clock times in a user-readable way. Function @getClockTime@ returns the current time in its internal representation. The expression @addToClockTime@~"d"~"t" adds a time difference "d" and a clock time "t" to yield a new clock time. The difference "d" may be either positive or negative. The expression @diffClockTimes@~"t1"~"t2" returns the difference between two clock times "t1" and "t2" as a @TimeDiff@. Function @toCalendarTime@~"t" converts "t" to a local time, modified by the timezone and daylight savings time settings in force at the time of conversion. Because of this dependence on the local environment, @toCalendarTime@ is in the @IO@ monad. Function @toUTCTime@~"t" converts "t" into a @CalendarTime@ in standard UTC format. @toClockTime@~"l" converts "l" into the corresponding internal @ClockTime@ ignoring the contents of the "ctWDay", "ctYDay", "ctTZName", and "ctIsDST" fields. Function @calendarTimeToString@ formats calendar times using local conventions and a formatting string. \subsection{Library {\tt Time}} \inputHS{code/Time} %**~header haskell98-report-20080907/libraries/io.verb0000644000175000017500000005624611345221573017721 0ustar marcotmarcot%**The Haskell 98 Library Report: IO %**~header \section{Input/Output} \label{IO} \index{input/output} \index{I/O} \indextt{IO} % Gotta break the figure ... \outline{ \inputHS{headers/IO} } \outline{ \inputHS{headers/IO1} } The monadic I/O system used in \Haskell{} is described by the \Haskell{} language report. Commonly used I/O functions such as @print@ are part of the standard prelude and need not be explicitly imported. This library contain more advanced I/O features. Some related operations on file systems are contained in the @Directory@ library. \subsection{I/O Errors} \index{I/O errors} \label{IOError} Errors of type @IOError@ are used by the I/O monad. This is an abstract type; the library provides functions to interrogate and construct values in @IOError@:\indextt{IOError} \begin{itemize} \item @isAlreadyExistsError@\indextt{isAlreadyExistsError} -- the operation failed because one of its arguments already exists. \item @isDoesNotExistError@\indextt{isDoesNotExistError} -- the operation failed because one of its arguments does not exist. \item @isAlreadyInUseError@\indextt{isAlreadyInUseError} -- the operation failed because one of its arguments is a single-use resource, which is already being used (for example, opening the same file twice for writing might give this error). \item @isFullError@\indextt{isFullError} -- the operation failed because the device is full. \item @isEOFError@\indextt{isEOFError} -- the operation failed because the end of file has been reached. \item @isIllegalOperation@\indextt{isIllegalOperation} -- the operation is not possible. \item @isPermissionError@\indextt{isPermissionError} -- the operation failed because the user does not have sufficient operating system privilege to perform that operation. \item @isUserError@\indextt{isUserError} -- a programmer-defined error value has been raised using @fail@.\indextt{fail} \end{itemize} All these functions return a @Bool@, which is @True@ if its argument is the corresponding kind of error, and @False@ otherwise. Any computation which returns an @IO@ result may fail with @isIllegalOperation@. Additional errors which could be raised by an implementation are listed after the corresponding operation. In some cases, an implementation will not be able to distinguish between the possible error causes. In this case it should return @isIllegalOperation@. Three additional functions are provided to obtain information about an error value. These are @ioeGetHandle@\indextt{ioeGetHandle} which returns @Just@~"hdl" if the error value refers to handle "hdl" and @Nothing@ otherwise; @ioeGetFileName@\indextt{ioeGetFileName} which returns @Just@~"name" if the error value refers to file "name", and @Nothing@ otherwise; and @ioeGetErrorString@\indextt{ioeGetErrorString} which returns a string. For ``user'' errors (those which are raised using @fail@), the string returned by @ioeGetErrorString@ is the argument that was passed to @fail@; for all other errors, the string is implementation-dependent. The @try@ function returns an error in a computation explicitly using the @Either@ type. The @bracket@ function captures a common allocate, compute, deallocate idiom in which the deallocation step must occur even in the case of an error during 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. \subsection{Files and Handles} \Haskell{} interfaces to the external world through an abstract {\em file system}\index{file system}. This file system is a collection of named {\em file system objects}, which may be organised in {\em directories}\index{directories} (see @Directory@). In some implementations, directories may themselves be file system objects and could be entries in other directories. For simplicity, any non-directory file system object is termed a {\em file}\index{file}, although it could in fact be a communication channel, or any other object recognised by the operating system. {\em Physical files}\index{physical file} are persistent, ordered files, and normally reside on disk. File and directory names are values of type @String@, whose precise meaning is operating system dependent. Files can be opened, yielding a handle which can then be used to operate on the contents of that file. \label{Handles} \index{handles} \Haskell{} defines operations to read and write characters from and to files, represented by values of type @Handle@. Each value of this type is a {\em handle}: a record used by the \Haskell{} run-time system to {\em manage} I/O with file system objects. A handle has at least the following properties: \begin{itemize} \item whether it manages input or output or both; \item whether it is {\em open}, {\em closed} or {\em semi-closed}; \item whether the object is seekable; \item whether buffering is disabled, or enabled on a line or block basis; \item a buffer (whose length may be zero). \end{itemize} Most handles will also have a current I/O position indicating where the next input or output operation will occur. A handle is {\em readable} if it manages only input or both input and output; likewise, it is {\em writable} if it manages only output or both input and output. A handle is {\em open} when first allocated. Once it is closed it can no longer be used for either input or output, though an implementation cannot re-use its storage while references remain to it. Handles are in the @Show@ and @Eq@ classes. The string produced by showing a handle is system dependent; it should include enough information to identify the handle for debugging. A handle is equal according to @==@ only to itself; no attempt is made to compare the internal state of different handles for equality. \subsubsection{Standard Handles} \label{StandardHandles} \index{standard handles} Three handles are allocated during program initialisation. The first two (@stdin@\indextt{stdin} and @stdout@\indextt{stdout}) manage input or output from the \Haskell{} program's standard input or output channel respectively. The third (@stderr@\indextt{stderr}) manages output to the standard error channel. These handles are initially open. \subsubsection{Semi-Closed Handles} \label{SemiClosed} \index{semi-closed handles} The operation "@hGetContents@ hdl"\indextt{hGetContents} (Section~\ref{hGetContents}) puts a handle "hdl" into an intermediate state, {\em semi-closed}. In this state, "hdl" is effectively closed, but items are read from "hdl" on demand and accumulated in a special list returned by @hGetContents@~"hdl". Any operation that fails because a handle is closed, also fails if a handle is semi-closed. The only exception is @hClose@. A semi-closed handle becomes closed: \begin{itemize} \item if @hClose@ is applied to it; \item if an I/O error occurs when reading an item from the handle; \item or once the entire contents of the handle has been read. \end{itemize} 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 evaluated prior to the handle becoming closed. Any I/O errors encountered while a handle is semi-closed are simply discarded. \subsubsection{File locking} Implementations should enforce as far as possible, at least locally to the \Haskell{} process, multiple-reader single-writer locking on files. That is, {\em there may either be many handles on the same file which manage input, or just one handle on the file which manages output}. If any open or semi-closed handle is managing a file for output, no new handle can be allocated for that file. If any open or semi-closed handle is managing a file for input, new handles can only be allocated if they do not manage output. Whether two files are the same is implementation-dependent, but they should normally be the same if they have the same absolute path name and neither has been renamed, for example. {\em Warning}: the @readFile@ operation (Section 7.1 of the Haskell Language Report) holds a semi-closed handle on the file until the entire contents of the file have been consumed. It follows that an attempt to write to a file (using @writeFile@, for example) that was earlier opened by @readFile@ will usually result in failure with @isAlreadyInUseError@. \indextt{readFile} \indextt{writeFile} \subsection{Opening and Closing Files} \label{OpeningClosing} \subsubsection{Opening Files} \label{Opening} \index{opening a file} \index{creating a file} Computation @openFile@~"file"~"mode"\indextt{openFile} allocates and returns a new, open handle to manage the file "file". % I don't believe this footnote is technically correct -- functions % are never computations IIRC: the computation is the action % that occurs when the function is applied to a state token -- KH % \footnote{We use % the term "computation" instead of "function" here to separate % functions which denote actions in the I/O monad from those outside the monad.} It manages input if "mode"\indextycon{IOMode} is @ReadMode@\indextt{ReadMode}, output if "mode" is @WriteMode@\indextt{WriteMode} or @AppendMode@,\indextt{AppendMode} and both input and output if mode is @ReadWriteMode@.\indextt{ReadWriteMode} If the file does not exist and it is opened for output, it should be created as a new file. If "mode" is @WriteMode@ and the file already exists, then it should be truncated to zero length. Some operating systems delete empty files, so there is no guarantee that the file will exist following an @openFile@ with "mode" @WriteMode@ unless it is subsequently written to successfully. The handle is positioned at the end of the file if "mode" is @AppendMode@, and otherwise at the beginning (in which case its internal I/O position is 0). The initial buffer mode is implementation-dependent. If @openFile@ fails on a file opened for output, the file may still have been created if it did not already exist. {\em Error reporting}: the @openFile@ computation may fail with @isAlreadyInUseError@ if the file is already open and cannot be reopened; @isDoesNotExistError@ if the file does not exist; or @isPermissionError@ if the user does not have permission to open the file. \indextt{isAlreadyInUseError} \indextt{isDoesNotExistError} \indextt{isPermissionError} \subsubsection{Closing Files} \label{Closing} \index{closing a file} Computation @hClose@~"hdl"\indextt{hClose} makes handle "hdl" closed. Before the computation finishes, if "hdl" is writable its buffer is flushed as for @hFlush@. Performing @hClose@ on a handle that has already been closed has no effect; doing so not an error. All other operations on a closed handle will fail. If @hClose@ fails for any reason, any further operations (apart from @hClose@) on the handle will still fail as if "hdl" had been successfully closed. \subsection{Determining the Size of a File} \label{FileSize} \index{size of file} For a handle "hdl" which is attached to a physical file, @hFileSize@\indextt{hFileSize} "hdl" returns the size of that file in 8-bit bytes ("\geq" 0). \subsubsection{Detecting the End of Input} \label{EOF} \index{end of file} For a readable handle "hdl", computation @hIsEOF@~"hdl"\indextt{hIsEOF} returns @True@ if no further input can be taken from "hdl"; for a handle attached to a physical file this means that the current I/O position is equal to the length of the file. Otherwise, it returns @False@. The computation @isEOF@\indextt{isEOF} is identical, except that it works only on @stdin@. % The computation may fail with: % \begin{itemize} % \item % @HardwareFault@ % A physical I/O error has occurred. % [@EIO@] % \item % @ResourceExhausted@ % Insufficient resources are available to perform the operation. % [@ENOMEM@] % \item % @IllegalOperation@ % The handle is not open for reading. % \end{itemize} \subsubsection{Buffering Operations} \label{Buffering} \index{file buffering} Three kinds of buffering are supported: line-buffering, block-buffering or no-buffering. These modes have the following effects. For output, items are written out, or {\em flushed}, from the internal buffer according to the buffer mode: \begin{itemize} \item {\bf line-buffering:} the entire buffer is flushed whenever a newline is output, the buffer overflows, a @hFlush@ is issued, or the handle is closed. \item {\bf block-buffering:} the entire buffer is written out whenever it overflows, a @hFlush@ is issued, or the handle is closed. \item {\bf no-buffering:} output is written immediately, and never stored in the buffer. \end{itemize} An implementation is free to flush the buffer more frequently, but not less frequently, than specified above. The buffer is emptied as soon as it has been written out. Similarly, input occurs according to the buffer mode for handle "hdl". \begin{itemize} \item {\bf line-buffering:} when the buffer for "hdl" is not empty, the next item is obtained from the buffer; otherwise, when the buffer is empty, characters are read into the buffer until the next newline character is encountered or the buffer is full. No characters are available until the newline character is available or the buffer is full. \item {\bf block-buffering:} when the buffer for "hdl" becomes empty, the next block of data is read into the buffer. \item {\bf no-buffering:} the next input item is read and returned. The @hLookAhead@\indextt{hLookAhead} operation (Section~\ref{hLookAhead}) implies that even a no-buffered handle may require a one-character buffer. \end{itemize} For most implementations, physical files will normally be block-buffered and terminals will normally be line-buffered. Computation @hSetBuffering@~"hdl"~"mode"\indextt{hSetBuffering} sets the mode of buffering for handle "hdl" on subsequent reads and writes. \begin{itemize} \item If "mode" is @LineBuffering@, line-buffering is enabled if possible. \item If "mode" is @BlockBuffering@~"size", then block-buffering is enabled if possible. The size of the buffer is "n" items if "size" is @Just @"n" and is otherwise implementation-dependent. \item If "mode" is @NoBuffering@, then buffering is disabled if possible. \end{itemize} If the buffer mode is changed from @BlockBuffering@ or @LineBuffering@ to @NoBuffering@, then \begin{itemize} \item if "hdl" is writable, the buffer is flushed as for @hFlush@; \item if "hdl" is not writable, the contents of the buffer is discarded. \end{itemize} {\em Error reporting}: the @hSetBuffering@ computation may fail with @isPermissionError@ if the handle has already been used for reading or writing and the implementation does not allow the buffering mode to be changed. Computation @hGetBuffering@~"hdl"\indextt{hGetBuffering} returns the current buffering mode for "hdl". The default buffering mode when a handle is opened is implementation-dependent and may depend on the file system object which is attached to that handle. \subsubsection{Flushing Buffers} \label{Flushing} \index{flushing a file buffer} Computation @hFlush@~"hdl"\indextt{hFlush} causes any items buffered for output in handle "hdl" to be sent immediately to the operating system. {\em Error reporting}: the @hFlush@ computation may fail with: @isFullError@ if the device is full; @isPermissionError@ if a system resource limit would be exceeded. It is unspecified whether the characters in the buffer are discarded or retained under these circumstances. \subsection{Repositioning Handles} \label{Seeking} \index{random access files} \index{seeking a file} \subsubsection{Revisiting an I/O Position} Computation @hGetPosn@~"hdl"\indextt{hGetPosn} returns the current I/O position of "hdl" as a value of the abstract type @HandlePosn@. If a call to "@hGetPosn@~h" returns a position "p", then computation @hSetPosn@~"p"\indextt{hSetPosn} sets the position of "h" to the position it held at the time of the call to @hGetPosn@. {\em Error reporting}: the @hSetPosn@ computation may fail with: @isPermissionError@ if a system resource limit would be exceeded. \subsubsection{Seeking to a new Position} Computation @hSeek@~"hdl"~"mode"~"i"\indextt{hSeek} sets the position of handle "hdl" depending on "mode".\indextycon{SeekMode} If "mode" is: \begin{itemize} \item @AbsoluteSeek@:\indextt{AbsoluteSeek} the position of "hdl" is set to "i". \item @RelativeSeek@:\indextt{RelativeSeek} the position of "hdl" is set to offset "i" from the current position. \item @SeekFromEnd@:\indextt{SeekFromEnd} the position of "hdl" is set to offset "i" from the end of the file. \end{itemize} The offset is given in terms of 8-bit bytes. If "hdl" is block- or line-buffered, then seeking to a position which is not in the current buffer will first cause any items in the output buffer to be written to the device, and then cause the input buffer to be discarded. Some handles may not be seekable (see @hIsSeekable@), or only support a subset of the possible positioning operations (for instance, it may only be possible to seek to the end of a tape, or to a positive offset from the beginning or current position). It is not possible to set a negative I/O position, or for a physical file, an I/O position beyond the current end-of-file. {\em Error reporting}: the @hSeek@ computation may fail with: @isPermissionError@ if a system resource limit would be exceeded. \subsection{Handle Properties} \label{Query} The functions @hIsOpen@\indextt{hIsOpen}, @hIsClosed@\indextt{hIsClosed}, @hIsReadable@\indextt{hIsReadable}, @hIsWritable@\indextt{hIsWritable} and @hIsSeekable@\indextt{hIsSeekable} return information about the properties of a handle. Each of these returns @True@ if the handle has the specified property, and @False@ otherwise. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Haskell 1.3 Text Input: LibReadTextIO %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Text Input and Output} \index{reading from a file} %\indextt{LibReadTextIO} Here we define a standard set of input operations for reading characters and strings from text files, using handles. Many of these functions are generalizations of Prelude functions. I/O in the Prelude generally uses @stdin@ and @stdout@; here, handles are explicitly specified by the I/O operation. \subsubsection{Checking for Input} \label{hReady} \label{hWaitForInput} \index{polling a handle for input} Computation @hWaitForInput@~"hdl"~"t"\indextt{hWaitForInput} waits until input is available on handle "hdl". It returns @True@ as soon as input is available on "hdl", or @False@ if no input is available within "t" milliseconds. Computation @hReady@~"hdl"\indextt{hReady} indicates whether at least one item is available for input from handle "hdl". {\em Error reporting}. The @hWaitForInput@ and @hReady@ computations fail with @isEOFError@ if the end of file has been reached. \subsubsection{Reading Input} Computation @hGetChar@~"hdl"\indextt{hGetChar} reads a character from the file or channel managed by "hdl". Computation @hGetLine@~"hdl"\indextt{hGetLine} reads a line from the file or channel managed by "hdl". The Prelude's @getLine@ is a shorthand for @hGetLine stdin@. {\em Error reporting}. The @hGetChar@ computation fails with @isEOFError@ if the end of file has been reached. The @hGetLine@ fails with @isEOFError@ if the end of file is encountered when reading the {\em first} character of the line. If @hGetLine@ encounters end-of-file at any other point while reading in a line, it is treated as a line terminator and the (partial) line is returned. \subsubsection{Reading Ahead} \label{hLookAhead} \index{lookahead} Computation @hLookAhead@~"hdl"\indextt{hLookAhead} returns the next character from handle "hdl" without removing it from the input buffer, blocking until a character is available. {\em Error reporting}: the @hLookAhead@ computation may fail with: @isEOFError@ if the end of file has been reached. \subsubsection{Reading The Entire Input} \label{hGetContents} \index{get the contents of a file} Computation @hGetContents@~"hdl"\indextt{hGetContents} returns the list of characters corresponding to the unread portion of the channel or file managed by "hdl", which is made semi-closed. {\em Error reporting}: the @hGetContents@ computation may fail with: @isEOFError@ if the end of file has been reached. \subsubsection{Text Output} Computation @hPutChar@~"hdl"~"c"\indextt{hPutChar} writes the character "c" to the file or channel managed by "hdl". Characters may be buffered if buffering is enabled for "hdl". Computation @hPutStr@~"hdl"~"s"\indextt{hPutStr} writes the string "s" to the file or channel managed by "hdl". Computation @hPrint@~"hdl"~"t"\indextt{hPrint} writes the string representation of "t" given by the @shows@ function to the file or channel managed by "hdl" and appends a newline. {\em Error reporting}: the @hPutChar@, @hPutStr@ and @hPrint@ computations may fail with: @isFull@-@Error@ if the device is full; or @isPermissionError@ if another system resource limit would be exceeded. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Haskell 1.3 Examples %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Examples} \index{input/output examples} Here are some simple examples to illustrate \Haskell{} I/O. \subsubsection{Summing Two Numbers} This program reads and sums two @Integer@s. \bprog @ import IO main = do hSetBuffering stdout NoBuffering putStr "Enter an integer: " x1 <- readNum putStr "Enter another integer: " x2 <- readNum putStr ("Their sum is " ++ show (x1+x2) ++ "\n") where readNum :: IO Integer -- Providing a type signature avoids reliance on -- the defaulting rule to fix the type of x1,x2 readNum = readLn @ \eprog \subsubsection{Copying Files} A simple program to create a copy of a file, with all lower-case characters translated to upper-case. This program will not allow a file to be copied to itself. This version uses character-level I/O. Note that exactly two arguments must be supplied to the program. \bprog @ import IO import System import Char( toUpper ) main = do [f1,f2] <- getArgs h1 <- openFile f1 ReadMode h2 <- openFile f2 WriteMode copyFile h1 h2 hClose h1 hClose h2 copyFile h1 h2 = do eof <- hIsEOF h1 if eof then return () else do c <- hGetChar h1 hPutChar h2 (toUpper c) copyFile h1 h2 @ \eprog An equivalent but much shorter version, using string I/O is: \bprog @ import System import Char( toUpper ) main = do [f1,f2] <- getArgs s <- readFile f1 writeFile f2 (map toUpper s) @ \eprog % Not any more in Haskell 98! % The @~@ used in the patterns above is a necessary consequence of the % @do@-notation which has been used for the I/O operations. In general, % if the pattern on the left of any @<-@ fails to match, the value of % the entire @do@-expression is defined to be the ``zero'' in the % underlying monad. However, since the @IO@ monad has no zero, the @~@ % is required in order to force the pattern to be irrefutable. Without % the @~@, a class error would occur because there is no instance of % @IO@ for class @MonadZero@. \subsection{Library @IO@} \inputHS{code/IO} %**~footer haskell98-report-20080907/libraries/README0000644000175000017500000000723311345221572017301 0ustar marcotmarcot 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). To chage the date on the report, you must change: * library.verb (line 415-ish) * index.html (line 8-ish) * html.config (~foot item) 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 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. haskell98-report-20080907/libraries/system.verb0000644000175000017500000000533311345221573020625 0ustar marcotmarcot%**The Haskell 98 Library Report: System functions %**~header \section{System Functions} \outline{ \inputHS{headers/System} } \indextt{ExitCode}\indextt{ExitSuccess}\indextt{ExitFailure} \indextt{getArgs}\indextt{getProgName}\indextt{getEnv} \indextt{system}\indextt{exitWith}\indextt{exitFailure} %% It would be less draconian to return [] for operations %% other than system, exitWith. KH This library describes the interaction of the program with the operating system. Any @System@ 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 must raise an @isIllegalOperation@. The @ExitCode@ type defines the exit codes that a program can return. @ExitSuccess@ indicates successful termination; and @ExitFailure@ "code" indicates program failure with value "code". The exact interpretation of "code" is operating-system dependent. In particular, some values of "code" may be prohibited (for instance, 0 on a POSIX-compliant system). Computation @getArgs@ returns a list of the program's command line arguments (not including the program name)\index{program arguments}. Computation @getProgName@ returns the name of the program as it was invoked\index{program name}. Computation @getEnv@~"var" returns the value of the environment variable "var"\index{environment variables}. If variable "var" is undefined, the @isDoesNotExistError@ exception is raised. Computation @system@~"cmd" returns the exit code produced when the operating system processes the command "cmd"\index{operating system commands}. Computation @exitWith@~"code" terminates the program, returning "code" to the program's caller\index{terminating a program}. Before the program terminates, any open or semi-closed handles are first closed. The caller may interpret the return code as it wishes, but the program should return @ExitSuccess@ to mean normal completion, and @ExitFailure @"n" to mean that the program encountered a problem from which it could not recover. The value @exitFailure@ is equal to @exitWith (ExitFailure @"exitfail"@)@, where "exitfail" is implementation-dependent. @exitWith@ bypasses the error handling in the I/O monad and cannot be intercepted by @catch@. If a program terminates as a result of calling @error@\indextt{error} or because its value is otherwise determined to be "\bot"\index{"\bot"}, then it is treated identically to the computation @exitFailure@. Otherwise, if any program "p" terminates without calling @exitWith@ explicitly, it is treated identically to the computation \bprog @(@"p"@ >> exitWith ExitSuccess) `catch` \ _ -> exitFailure@ \eprog \indextt{catch} %**~footer haskell98-report-20080907/libraries/introduction.verb0000644000175000017500000000612611345221573022023 0ustar marcotmarcot%**The Haskell 98 Library Report: Introduction %**~sheader \markboth{PREFACE}{PREFACE} \begin{center} {\Large \bf Preface} \end{center} \vspace{.2in} This document defines the standard libraries for \Haskell{} 98. The libraries presented here represent a selection of basic functionality that is expected to be useful to many \Haskell{} programmers. Most implementations provide further libraries which are not a recognized part of the \Haskell{} standard. The latest version of this report, as well many other available libraries, can be found on the web at @http://haskell.org@. \subsection*{The August 2001 Revision} Both Haskell 98 Reports were revised in August 2001, to incorporate dozens of typographical errors and presentational improvements. A complete list of all changes can be found at @http://haskell.org@. \subsection*{Acknowledgements} We would like to express our thanks to those who have contributed directly or indirectly to this report without being named as authors, including Olaf Chitil, Mark Carroll, Tony Davie, Hal Daume, Sigbjorn Finne, Andy Gill, Mike Gunter, Fergus Henderson, Orjan Johansen, Kent Karlsson, Sandra Loosemore, Graeme Moss, Sven Panne, Keith Wansbrough. In addition, many people named in the Acknowledgements to the Haskell 98 Language Report also contributed to the Library Report. \clearpage \section{Introduction} \label{introduction} This document defines the standard libraries for \Haskell{} 98. Like the @Prelude@, these libraries are a required part of a \Haskell{} implementation. Unlike the Prelude, however, these modules must be {\em explicitly} imported into scope. When possible, library functions are described solely by executable \Haskell{} code. Functions which require implementation-dependent primitives are represented by type signatures without definitions. Some data types are implementation-dependent: these are indicated by comments in the source. The code found here is a {\em specification}, rather than an {\em implementation}. Implementations may choose more efficient versions of these functions. However, all properties of these specifications must be preserved, including strictness properties. Classes defined in libraries may be derivable. This report includes the derivation of such classes when appropriate. When @Prelude@ types are instances of derivable library classes a commented empty instance declaration is used. The comment, ``as derived'', indicates that the instance is the same as would have been generated by a @deriving@ in the Prelude type declaration. The following table summarises the fixities of all the operators introduced by the standard libraries: \begin{table}[htb] \[ \centerline{ \begin{tabular}{|r||l|l|l|} \hline Prec- & Left associative & Non-associative & Right associative \\ edence & operators & operators & operators \\ \hline\hline 9 & @Array.!@, @Array.//@ & & \\ \hline 7 & @Ratio.%@ & & \\ \hline 6 & & @Complex.:+@ & \\ \hline 5 & & @List.\\@ & \\ \hline \end{tabular}} \] \ecaption{Precedences and fixities of library operators} \indextt{>>=} \end{table} %**~sfooter haskell98-report-20080907/libraries/index-intro.verb0000644000175000017500000000014211345221573021532 0ustar marcotmarcotCode entities are shown in @typewriter@ font. Ordinary index entries are shown in a roman font. haskell98-report-20080907/libraries/random.verb0000644000175000017500000002270211345221573020560 0ustar marcotmarcot%**The Haskell 98 Library Report: Random Numbers %**~eheader \section{Random Numbers} \label{random numbers} \outline { \inputHS{headers/Random} } The @Random@ library deals with the common task of pseudo-random number generation. The library makes it possible to generate repeatable results, by starting with a specified initial random number generator; or to get different results on each run by using the system-initialised generator, or by supplying a seed from some other source. The library is split into two layers: \begin{itemize} \item A core {\em random number generator} provides a supply of bits. The class @RandomGen@ provides a common interface to such generators. \item The class @Random@ provides a way to extract particular values from a random number generator. For example, the @Float@ instance of @Random@ allows one to generate random values of type @Float@. \end{itemize} \subsection{The @RandomGen@ class, and the @StdGen@ generator} The class @RandomGen@ provides a common interface to random number generators. \bprog @ class RandomGen g where genRange :: g -> (Int,Int) next :: g -> (Int, g) split :: g -> (g, g) -- Default method genRange g = (minBound,maxBound) @ \eprog \indextt{next} \indextt{split} \indextt{genRange} \indextt{RandomGen} \begin{itemize} \item The @genRange@ operation yields the range of values returned by the generator. It is required that: \begin{itemize} \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 argument, and hence the value it returns can be determined only by the instance of @RandomGen@. That in turn allows an implementation to make a single call to @genRange@ to establish a generator's range, without being concerned that the generator returned by (say) @next@ might have a different range to the generator passed to @next@. \item The @next@ operation returns an @Int@ that is uniformly distributed in the range returned by @genRange@ (including both end points), and a new generator. \item The @split@ operation allows one to obtain two independent random number generators. This is very useful in functional programs (for example, when passing a random number generator down to recursive calls), but very little work has been done on statistically robust implementations of @split@ ([1,4] are the only examples we know of). \end{itemize} The @Random@ library provides one instance of @RandomGen@, the abstract data type @StdGen@: \bprog @ data StdGen = ... -- Abstract instance RandomGen StdGen where ... instance Read StdGen where ... instance Show StdGen where ... mkStdGen :: Int -> StdGen @ \eprog \indextt{StdGen} \indextt{mkStdGen} The @StgGen@ instance of @RandomGen@ has a @genRange@ of at least 30 bits. The result of repeatedly using @next@ should be at least as statistically robust as the ``Minimal Standard Random Number Generator'' described by [2,3]. Until more is known about implementations of @split@, all we require is that @split@ deliver generators that are (a) not identical and (b) independently robust in the sense just given. The @Show@/@Read@ instances of @StdGen@ provide a primitive way to save the state of a random number generator. It is required that @read (show g) == g@. In addition, @read@ may be used to map an arbitrary string (not necessarily one produced by @show@) onto a value of type @StdGen@. In general, the @read@ instance of @StdGen@ has the following properties: \begin{itemize} \item It guarantees to succeed on any string. \item It guarantees to consume only a finite portion of the string. \item Different argument strings are likely to result in different results. \end{itemize} The function @mkStdGen@ provides an alternative way of producing an initial generator, by mapping an @Int@ into a generator. Again, distinct arguments should be likely to produce distinct generators. Programmers may, of course, supply their own instances of @RandomGen@. {\em Implementation warning.} A superficially attractive implementation of @split@ is \bprog @ instance RandomGen MyGen where ... split g = (g, variantOf g) @ \eprog Here, @split@ returns @g@ itself and a new generator derived from @g@. But now consider these two apparently-independent generators: \bprog @ g1 = snd (split g) g2 = snd (split (fst (split g))) @ \eprog If @split@ genuinely delivers independent generators (as specified), then @g1@ and @g2@ should be independent, but in fact they are both equal to @variantOf g@. Implementations of the above form do not meet the specification. \subsection{The @Random@ class} With a source of random number supply in hand, the @Random@ class allows the programmer to extract random values of a variety of types: \bprog @ class Random a where randomR :: RandomGen g => (a, a) -> g -> (a, g) random :: RandomGen g => g -> (a, g) randomRs :: RandomGen g => (a, a) -> g -> [a] randoms :: RandomGen g => g -> [a] randomRIO :: (a,a) -> IO a randomIO :: IO a -- Default methods randoms g = x : randoms g' where (x,g') = random g randomRs = ...similar... randomIO = getStdRandom random randomRIO range = getStdRandom (randomR range) instance Random Int where ... instance Random Integer where ... instance Random Float where ... instance Random Double where ... instance Random Bool where ... instance Random Char where ... @ \eprog \indextt{Random} \indextt{random} \indextt{randomR} \indextt{randoms} \indextt{randomRs} \indextt{randomIO} \indextt{randomRIO} \begin{itemize} \item @randomR@ takes a range "(lo,hi)" and a random number generator "g", and returns a random value uniformly distributed in the closed interval "[lo,hi]", together with a new generator. It is unspecified what happens if "lo>hi". For continuous types there is no requirement that the values "lo" and "hi" are ever produced, but they may be, depending on the implementation and the interval. % \begin{itemize} % \item For discrete types (such as @Int@ or @Bool@), % ``uniformly distributed'' means that each value is equally likely to occur. % \item For floating-point types (instances of @Floating@, such as @Float@ or @Double@), % the probability of any particular (representable) value "v" % occurring is proportional to "ulp(v)/(h-l)", where "ulp(v)" is the % size of a unit change in the least significant bit position of "v". % \item For continuous types, such as @Rational@, ``uniformly distributed'' means % that the probability distribution of returned values is uniform over the interval. % \end{itemize} % \begin{itemize} % \item For discrete types (such as @Int@ or @Bool@), the range is the closed interval "[l,h]". % \item For fractional types (instances of @Fractional@, such as @Float@ or @Double@), % the range is the semi-closed interval "[l,h)". % \end{itemize} % for discrete types, or if "l \geq h" for fractional types. \item @random@ does the same as @randomR@, but does not take a range. \begin{itemize} \item For bounded types (instances of @Bounded@, such as @Char@), the range is normally the whole type. \item For fractional types, the range is normally the semi-closed interval "[0,1)". \item For @Integer@, the range is (arbitrarily) the range of @Int@. \end{itemize} \item The plural versions, @randomRs@ and @randoms@, produce an infinite list of random values, and do not return a new generator. \item The @IO@ versions, @randomRIO@ and @randomIO@, use the global random number generator (see Section~\ref{global-rng}). \end{itemize} \subsection{The global random number generator} \label{global-rng} There is a single, implicit, global random number generator of type @StdGen@, held in some global variable maintained by the @IO@ monad. It is initialised automatically in some system-dependent fashion, for example, by using the time of day, or Linux's kernel random number generator. To get deterministic behaviour, use @setStdGen@. \bprog @ setStdGen :: StdGen -> IO () getStdGen :: IO StdGen newStdGen :: IO StdGen getStdRandom :: (StdGen -> (a, StdGen)) -> IO a @ \eprog \indextt{setStdGen} \indextt{getStdGen} \indextt{newStdGen} \indextt{getStdRandom} \begin{itemize} \item @getStdGen@ and @setStdGen@ get and set the global random number generator, respectively. \item @newStdGen@ applies @split@ to the current global random generator, updates it with one of the results, and returns the other. \item @getStdRandom@ uses the supplied function to get a value from the current global random generator, and updates the global generator with the new generator returned by the function. For example, @rollDice@ gets a random integer between 1 and 6: \bprog @ rollDice :: IO Int rollDice = getStdRandom (randomR (1,6)) @ \eprog \end{itemize} \subsection*{References} \begin{description} \item[{[1]}] FW Burton and RL Page, ``Distributed random number generation'', Journal of Functional Programming, 2(2):203-212, April 1992. \item[{[2]}] SK Park, and KW Miller, ``Random number generators - good ones are hard to find'', Comm ACM 31(10), Oct 1988, pp1192-1201. \item[{[3]}] DG Carta, ``Two fast implementations of the minimal standard random number generator'', Comm ACM, 33(1), Jan 1990, pp87-88. \item[{[4]}] P Hellekalek, ``Don't trust parallel Monte Carlo'', Department of Mathematics, University of Salzburg, @http://random.mat.sbg.ac.at/~peter/pads98.ps@, 1998. \end{description} The Web site @http://random.mat.sbg.ac.at/@ is a great source of information. %**~efooter haskell98-report-20080907/libraries/list.verb0000644000175000017500000001552711345221573020262 0ustar marcotmarcot%**The Haskell 98 Library Report: List Utilities %**~header \section{List Utilities} \outline{ \inputHS{headers/List} } \outline{ \inputHS{headers/List1} } This library defines some lesser-used operations over lists. \subsection{Indexing lists} \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)@. \item @elemIndices val list@\indextt{elemIndices} returns an in-order list of indices, giving the occurrences of @val@ in @list@. \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} There are a number of ``set'' operations defined over the @List@ type. @nub@ (meaning ``essence'') removes duplicates elements from a list. @delete@, @(\\)@, @union@ and @intersect@ (and their @By@ variants) preserve the invariant their result does not contain duplicates, provided that their first argument contains no duplicates. \begin{itemize} \item @nub@\indextt{nub} removes duplicate elements from a list. For example: \bprog @ nub [1,3,1,4,3,3] = [1,3,4] @ \eprog \item @delete x@\indextt{delete} removes the first occurrence of @x@ from its list argument, e.g., \bprog @ delete 'a' "banana" == "bnana" @ \eprog \item @(\\)@\indextt{(\\)} is list difference (non-associative). In the result of @xs \\ ys@, the first occurrence of each element of @ys@ in turn (if any) has been removed from @xs@. Thus, @(xs ++ ys) \\ xs == ys@. \item @union@\indextt{union} is list union, e.g., \bprog @ "dog" `union` "cow" == "dogcw" @ \eprog \item @intersect@\indextt{intersect} is list intersection, e.g., \bprog @ [1,2,3,4] `intersect` [2,4,6,8] == [2,4] @ \eprog \end{itemize} \subsection{List transformations} \begin{itemize} \item @intersperse sep@\indextt{intersperse} inserts @sep@ between the elements of its list argument, e.g., \bprog @ intersperse ',' "abcde" == "a,b,c,d,e" @ \eprog \item @transpose@\indextt{transpose} transposes the rows and columns of its argument, e.g., \bprog @ transpose [[1,2,3],[4,5,6]] == [[1,4],[2,5],[3,6]] @ \eprog \item @partition@\indextt{partition} takes a predicate and a list and returns a pair of lists: those elements of the argument list that do and do not satisfy the predicate, respectively; i.e., \bprog @ partition p xs == (filter p xs, filter (not . p) xs) @ \eprog \item @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 example \bprog @ group "Mississippi" == ["M","i","ss","i","ss","i","pp","i"] @ \eprog \item @inits@\indextt{inits} returns the list of initial segments of its argument list, shortest first. \bprog @ inits "abc" == ["","a","ab","abc"] @ \eprog \item @tails@\indextt{tails} returns the list of all final segments of its argument list, longest first. \bprog @ tails "abc" == ["abc", "bc", "c",""] @ \eprog \item @mapAccumL f s l@\indextt{mapAccumL} applies @f@ to an accumulating ``state'' parameter @s@ and to each element of @l@ in turn. \item @mapAccumR@\indextt{mapAccumR} is similar to @mapAccumL@ except that the list is processed from right-to-left rather than left-to-right. \end{itemize} \subsection{@unfoldr@} The @unfoldr@ function is a `dual' to @foldr@: while @foldr@ reduces a list to a summary value, @unfoldr@ builds a list from a seed value. For example: \bprog @ iterate f == unfoldr (\x -> Just (x, f x)) @ \eprog In some cases, @unfoldr@ can undo a @foldr@ operation: \bprog @ unfoldr f' (foldr f z xs) == xs @ \eprog if the following holds: \bprog @ f' (f x y) = Just (x,y) f' z = Nothing @ \eprog \subsection{Predicates} @isPrefixOf@ and @isSuffixOf@ check whether the first argument is a prefix (resp. suffix) of the second argument. \subsection{The ``@By@'' operations} By convention, overloaded functions have a non-overloaded counterpart whose name is suffixed with ``@By@''. For example, the function @nub@ could be defined as follows: \bprog @ nub :: (Eq a) => [a] -> [a] nub [] = [] nub (x:xs) = x : nub (filter (\y -> not (x == y)) xs) @ \eprog However, the equality method may not be appropriate in all situations. The function: \bprog @ nubBy :: (a -> a -> Bool) -> [a] -> [a] nubBy eq [] = [] nubBy eq (x:xs) = x : nubBy eq (filter (\y -> not (eq x y)) xs) @ \eprog allows the programmer to supply their own equality test. When the ``@By@'' function replaces an @Eq@ context by a binary predicate, the predicate is assumed to define an equivalence; when the ``@By@'' 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@, @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. % Several of the functions defined here are derivatives of, or % related to, Prelude functions. These functions are % @elem@, @maximum@, @minimum@, @zip@, @zip3@, @zipWith@, % @zipWith3@, @unzip@, @unzip3@, % [according to Keith] @take@, @drop@, @splitAt@, @index@, @replicate@. \subsection{The ``@generic@'' operations} The prefix ``@generic@'' indicates an overloaded function that is a generalised version of a @Prelude@ function. For example, \bprog @ genericLength :: Integral a => [b] -> a @ \eprog is a generalised version of @length@. The ``@generic@'' operations are as follows: @genericLength@, @genericTake@, @genericDrop@, @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}} \label{List} \inputHS{code/List} %**~footer haskell98-report-20080907/styles/0000755000175000017500000000000011345221573015764 5ustar marcotmarcothaskell98-report-20080907/styles/grammar.sty0000644000175000017500000001016311345221573020154 0ustar marcotmarcot%%% LaTeX2e package file to set EBNF in the style of the Haskell report %%% %%% Manuel M. T. Chakravarty [1997..2001] %%% %%% $Id: grammar.sty,v 1.1 2003/01/14 06:58:33 chak Exp $ %%% %%% This file is free software; you can redistribute it and/or modify %%% it under the terms of the GNU General Public License as published by %%% the Free Software Foundation; either version 2 of the License, or %%% (at your option) any later version. %%% %%% This file is distributed in the hope that it will be useful, %%% but WITHOUT ANY WARRANTY; without even the implied warranty of %%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the %%% GNU General Public License for more details. %%% %%% DOCU ====================================================================== %%% %%% As a cheap (and ineffective) substitute for proper documentation, here an %%% example using the macros: %%% %%% \begin{grammar} %%% \grule{ftype}{% %%% \gnterm{frtype}} %%% \gor{% %%% \gnterm{fatype} -> \gnterm{ftype}} %%% \grule{frtype}{% %%% \gnterm{fatype}} %%% \gor{% %%% ()} %%% \grule[$k\geq0$]{fatype}{% %%% \gnterm{qtycon} \gnterm[1]{atype} \gellipse\ \gnterm[k]{atype}} %%% \end{grammar} %%% %%% TODO ====================================================================== %%% %%% * flexible way of determining the column width is needed (should be the %%% same throughout a single grammar (or even the whole document) %%% \ProvidesPackage{grammar}[2001/04/17, v0.5a, ] \RequirePackage{ifthen} % font configuration % % * these two commands can be redefined to change the default fonts for % terminals and non-terminals, respectively % \newcommand{\gtermfont}{\ttfamily} \newcommand{\gntermfont}{\rmfamily\itshape} % remembers whether we are in the star form of the grammar environment % (internal) % \newif\if@quoted % grammar environment % % * typeset in paragraph mode within a tabular % * there are four columns, containing the nonterminal, rule symbol (-> or |), % the rules rhs, and a comment, respectively % * the star form of the command is not `quote'd % \newenvironment{grammar}{% \@quotedtrue \@grammar }{% \@endgrammar } \newenvironment{grammar*}{% \@quotedfalse \@grammar }{% \@endgrammar } % internal implementation of the grammar environment % \newcommand{\@grammar}{% \gtermfont % for terminals \if@quoted\quote\fi \tabular{@{}lcl@{\quad}l@{}} } \newcommand{\@endgrammar}{% \endtabular \if@quoted\endquote\fi \ignorespaces\global\@ignoretrue } % a rule: optional comment, lhs, and rhs % \newcommand{\grule}[3][!*NEVER USED ARGUMENT*!]{% \ifthenelse{\equal{#1}{!*NEVER USED ARGUMENT*!}}{% \gnterm{#2} &$\rightarrow$& #3 \\ }{% \gnterm{#2} &$\rightarrow$& #3 & \rmfamily(#1)\\ }% } % a rule alternative: optional comment and rhs % \newcommand{\gor}[2][!*NEVER USED ARGUMENT*!]{% \ifthenelse{\equal{#1}{!*NEVER USED ARGUMENT*!}}{% &$|$& #2\\ }{% &$|$& #2 & \rmfamily(#1)\\ }% } % set a non-terminal with an optimal subscript % \newcommand{\gnterm}[2][!*NEVER USED ARGUMENT*!]{% \bgroup \gntermfont#2% \ifthenelse{\equal{#1}{!*NEVER USED ARGUMENT*!}}\relax{% \(_{#1}\)% }% \egroup } \newcommand{\galt}{$|$} % inline alternatives \newcommand{\gellipse}{\textrm{\ldots}} % ellipses \newcommand{\ggroup}[1]{\textrm(#1\textrm)} % grouped expression \newcommand{\gopt}[1]{\textrm[#1\textrm]} % optinal term \newcommand{\grepeat}[1]{\textrm\{#1\textrm\}} % repeated term \newcommand{\gminus}[1]{% % set difference \(_{\langle\mbox{\scriptsize #1}\rangle}\)} \newcommand{\gverbal}[1]{{\rmfamily\textbf{#1}}}% informal description % the following command is for terminals, but it is not necessary with the % `grammar' environment, as terminals are the default; it is however useful in % the rest of the text % \newcommand{\gterm}[1]{{\normalfont\gtermfont#1}} % some characters that are difficult to denote % \newcommand{\gbackslash}{\char"5C} \newcommand{\gtilde}{\char"7E} \newcommand{\ghat}{\char"5E} haskell98-report-20080907/styles/proof.sty0000644000175000017500000002231711345221573017657 0ustar marcotmarcot% % version 3.0 (for both LaTeX 2.09 and LaTeX 2e) % Mar 6, 1997 % Copyright (C) 1990 -- 1997, Makoto Tatsuta (tatsuta@kusm.kyoto-u.ac.jp) % % This program is free software; you can redistribute it or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either versions 1, or (at your option) % any later version. % % This program is distributed in the hope that it will be useful % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % Usage: % In \documentstyle, specify an optional style `proof', say, % \documentstyle[proof]{article}. % % The following macros are available: % % In all the following macros, all the arguments such as % and are processed in math mode. % % \infer % draws an inference. % % Use & in to delimit upper formulae. % consists more than 0 formulae. % % \infer returns \hbox{ ... } or \vbox{ ... } and % sets \@LeftOffset and \@RightOffset globally. % % \infer[