Late Dec release
authorSimon Peyton Jones <simonpj@microsoft.com>
Fri, 21 Dec 2001 16:00:25 +0000 (16:00 +0000)
committerSimon Peyton Jones <simonpj@microsoft.com>
Fri, 21 Dec 2001 16:00:25 +0000 (16:00 +0000)
39 files changed:
haskell98-bugs.html
libraries/array.verb
libraries/char.verb
libraries/code/Char.hs
libraries/code/IO.hs
libraries/code/List.hs
libraries/code/Numeric.hs
libraries/directory.verb
libraries/headers/Char.hs
libraries/headers/IO.hs
libraries/headers/List.hs
libraries/headers/Numeric.hs
libraries/html.config
libraries/index.html
libraries/io.verb
libraries/library.verb
libraries/list.verb
libraries/monad.verb
libraries/numeric.verb
libraries/random.verb
report/Prelude.hs
report/PreludeIO.hs
report/PreludeList.hs
report/PreludeText.hs
report/basic.verb
report/decls.verb
report/exps.verb
report/haskell.bbl
report/haskell.verb
report/html.config
report/index-extra.verb
report/index.html
report/io-13.verb
report/lexemes.verb
report/literate.verb
report/modules.verb
report/standard-prelude.verb
report/syntax-iso.verb
report/syntax-lexical.verb

index 8c47085..113ed43 100644 (file)
@@ -43,7 +43,7 @@ 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</em>.
 <p>
-"Though the kernel is not formally specified, it is essentially a
+"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
@@ -61,25 +61,31 @@ 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.
 
-<p><li> <strong>Page 5, Section 2.2, Lexical program structure; and Appendix B.2, p120.</strong>
-Change the production for <em>uniDigit</em> to
+<p><li> [Late Dec 2001] <strong>Page 5, Section 2.2, Lexical program structure; and Appendix B.2, p120.</strong>
+Replace the production for "comment" with:
 <pre>
-  uniDigit -> any Unicode decimal digit
+  comment         -> dashes [ any_&lt;symbol&gt;  { any } \] newline
 </pre>
+(This ensures that "--+", for example, does not start a comment.)
 
-<p><li> <strong>Page 5, Section 2.2, Lexical program structure; and Appendix B.2, p120.</strong>
-Change the production for <em>symbol</em> to:
+<p><li> [Dec 2001] <strong>Page 5, Section 2.2, Lexical program structure; and Appendix B.2, p120.</strong>
+<ul>
+<li> Change the production for <em>lexeme</em> to
 <pre>
-   symbol -> ascSymbol | uniSymbol&lt; special | _ | : | " | ' &gt;
+ lexeme -> qvarid | qconid | qvarsym | qconsym | literal | special | reservedop | reservedid
+</pre>
+<p> <li> Change the production for <em>uniDigit</em> to
+<pre>
+  uniDigit -> any Unicode decimal digit
 </pre>
 
-<p><li> <strong>Page 5, Section 2.2, Lexical program structure; and Appendix B.2, p120.</strong>
-<ul>
-<li> Add <em>return</em>, <em>linefeed</em>, and <em>uniWhite</em> to the production for <em>ANY</em>.
-<li> Replace the production for <em>lexeme</em> with:
+<p> <li> Change the production for <em>symbol</em> to:
 <pre>
-  lexeme -> qvarid | qconid | qop | literal | special | reservedop | reservedid
+   symbol -> ascSymbol | uniSymbol&lt; special | _ | : | " | ' &gt;
 </pre>
+
+<p> <li> Add <em>return</em>, <em>linefeed</em>, and <em>uniWhite</em> to the production for <em>ANY</em>.
+
 </ul>
 (These changes, and the next one, justify the productions for <em>program</em> which claims that a program is
 a sequence of lexemes and white space.)
@@ -114,7 +120,7 @@ to the end of Section 2.4.  (These paragraphs deal with lexical matters, which d
 <p><li> <strong>Page 9, Section 2.6, Character and String Literals.</strong>
 In the production for "cntrl" replace "ASClarge" by "ascLarge".
 
-<p><li> [Oct 2001]  <strong>Page 9, Section 2.6, Characters and String Literals; and 
+<p><li> [Nov 2001]  <strong>Page 9, Section 2.6, Characters and String Literals; and 
 Page 73, Section 6.1.2, Characters and strings</strong>
 <ul>
 <li> In Section 2.6, delete the last sentence of the third paragraph "Numeric escapes
@@ -123,13 +129,14 @@ that are out of range...".
 <li> In Section 6.1.2, replace the first sentence of the section by
 <p>
 "The character type <tt>Char</tt>
-is an enumeration whose values represent Unicode characters [10]."
+is an enumeration whose values represent Unicode characters [10]."  Similarly,
+remove the final clause "...in the range [0..2^16 - 1]".
 </ul>
 <p>
-This change removes the commitment to 16-bit Unicode.  The result is that the Report
+(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.
+in a revision of this nature.)
 
 <p><li> <strong>Page 10, Section 2.7, Layout.</strong>
 In the middle of the third paragraph, just before the sentence beginning
@@ -293,6 +300,46 @@ a data declaration."
 Change "occurance" to "occurrence" in the translation box at the very end of
 the section.
 
+<p><li> [Late Dec 2001] <strong>Page 46, Section 4.3.2, Instance Declarations.</strong>
+<ul>
+<li> Remove the production for "qfunlhs".
+<li> Replace the first production for "idecl" by:
+<pre>
+  idecl -> (funlhs | var) rhs
+</pre>
+(i.e. omitting the alternatives for "qvar" and "qfunlhs").
+<li> 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.".
+<li> In place of the deleted sentences, add the following:
+<p>
+"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 <tt>return</tt> is in scope only
+with the qualified name <tt>Monad.return</tt>.
+<pre>
+  module A where
+    import qualified Monad
+
+    instance Monad.Monad T where
+      return = ...
+      (>>=)  = ...
+</pre>
+"
+<li> Make the same syntactic changes to the syntax in Appendix B.4.
+</ul>
+(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.)
+
+
+<p><li> [Late Dec 2001]  <strong>Page 49, Section 4.3.4, Ambiguous Types...</strong>  In the third paragraph
+from the end of 4.3.4, replace "monotype" by "type".
+
 <p><li> <strong>Page 49, Section 4.3.4, Ambiguous Types...</strong>
 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..."
@@ -363,6 +410,31 @@ is affected by module boundaries."
 <p>
 This footnote qualifies the otherwise over-strong statement.
 
+<p><li> [Late Dec 2001] <strong>Page 63,64, Section 5.2, Export lists</strong>.
+<ul>
+<li> In the production for "export", replace "qcname" by "cname" (and similarly in Appendix B.4).
+<li> 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".
+<li> In the second bulleted item under point (2) of the numbered items, replace "qcname" by "c", throughout.
+<li> In point (2) of the numbered items, add the following:
+<p>
+"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</em>. For example, the following is 
+legal
+<pre>
+  module A( Mb.Maybe( Nothing, Just ) ) where
+    import qualified Maybe as Mb
+</pre>
+"
+<li> Make a similar change to point (4).
+<li> In points (1)-(4), make it clear that the variable, type constructor, or class must be in scope.
+</ul>
+(These changes clarify the scope rules for export lists.  Much email discussion during Dec 2001.)
+
 <p><li> [Oct 2001] <strong>Page 64, Section 5.2, Export declarations, numbered items 5 and 6.</strong>
 Replace both items with the following:
 <p>
@@ -518,16 +590,6 @@ reference to <tt>null</tt> must also resolve the ambiguous use of <tt>null</tt>
 just as <tt>A</tt> does.  Thus there is little danger of accidentally shadowing 
 Prelude names."
 
-<p><li> [Nov 2001]  <strong>Page 73, Section 6.1.2, Characters and strings.</strong>
-Replace the first sentence to read:
-<p>
-"The character type <tt>Char</tt> is an enumeration whose values represent 
-Unicode characters."
-<p>
-(This change withdraws the specification that Chars are 16 bits.  According to the Unicode
-experts, the rest of the Report is gloriously vague wrt to Unicode, and fixing to 16 bits
-here is inappropriate precision.)
-
 <p><li> [Aug 2001]  <strong>Page 74, Section 6.1.3, Lists.</strong>  In the last sentence,
 after "<tt>Monad</tt>" add ", <tt>Functor</tt>".  (The list type is an instance of <tt>Functor</tt>.)
 
@@ -581,12 +643,14 @@ precedence of the enclosing context (see Appendix D.4)."
 Page 19, Section 3.10 Arithmetic Sequences; and Appendix D.2, Derived instances of Enum.</strong>
 <ul>
 <li> Move the specification of the <tt>Int</tt> and <tt>Integer</tt> instances of
-<tt>Enum</tt> 3.10 to 6.3.4.
+<tt>Enum</tt> from 3.10 to 6.3.4.
 <li> Specify that, for bounded types, <tt>succ</tt> and <tt>pred</tt> should fail 
 when applied to <tt>maxBound</tt> and <tt>minBound</tt> resp.
 <li> Specify that the <tt>enum</tt> functions on numeric types are strict.
 <li> Remove material from D.2 so that it describes only the derived instances.
 </ul>
+This change amounts to a fairly complete rewrite of 6.3.4, with a slightly tighter
+specification than before.
 
 <p><li><strong>Page 80, Section 6.3.6, Class Monad.</strong>
 Right at the bottom of the page, replace "However, for IO, the fail
@@ -608,6 +672,15 @@ should be replaced by
     realToFrac :: (Real a, Fractional b) => a -> b
 </pre>
 
+<p><li> [Late Dec 2001] <strong>Page 84, Section 6.4.2, <tt>gcd</tt></strong>.
+In the final paragraph of 6.4.2, replace "<tt>gcd</tt> x y is the greatest integer
+that divides both x and y" by "<tt>gcd</tt> x y is the greatest (positive) integer
+that divides both x and y.   <tt>gcd 0 0</tt> raises a runtime error".
+<p>
+(The "(positive)" clarifies a slightly ambiguous point, while the specification for
+<tt>gcd 0 0</tt> remains controversial.  
+There was a lot of email on the Haskell mailing list in Dec 2001 about the latter point.)
+
 <p><li><strong>Page 88, Section 7.1, Standard I/O functions.</strong>
 In the section "Input functions" replace "the <tt>IOError</tt> value associated
 with end-of-file is defined in a library" by "a predicate <tt>isEOFError</tt> that 
@@ -632,6 +705,30 @@ After the above signature for <tt>userError</tt>, add the following:
     fail s = ioError (userError s)
 </pre>"
 
+<p><li> [Dec 2001] <strong>Page 91, Appendix A, Standard Prelude.</strong>
+<ul>
+<li>
+Add the following paragraph to clarify the status of the default-method definitions.
+<p>
+"The default method definitions, given with <tt>class</tt> declarations, constitute
+a specification <em>only</em> of the default method.  They do <em>not</em> constitute a
+specification of the meaning of the method in all instances.  To take
+one particular example, the default method for <tt>enumFrom</tt> in class <tt>Enum</tt>
+will not work properly for types whose range exceeds that of <tt>Int</tt> (because
+<tt>fromEnum</tt> cannot map all values in the type to distinct <tt>Int</tt> values)."
+<p>
+<li> Add the following paragraph, to say why some functions have an unexpectedly
+restricted type:
+<p>
+"To reduce the occurrence of unexpected ambiguity errors, and to
+improve efficiency, a number of commonly-used functions over lists use
+the <tt>Int</tt> type rather than using a more general numeric type, such as
+<tt>Integral a</tt> or <tt>Num a</tt>.  These functions are: <tt>take</tt>, <tt>drop</tt>,
+<tt>index</tt>, <tt>length</tt>, <tt>splitAt</tt>, and <tt>replicate</tt>.  The more general
+versions are given in the <tt>List</tt> library, with the prefix
+"<tt>generic</tt>"; for example <tt>genericLength</tt>."
+</ul>
+
 <p><li> [Oct 2001] <strong>Page 93, Appendix A, Standard Prelude.</strong>
 Replace the fixity declaration for <tt>(:)</tt> by the following comments:
 <pre>
@@ -641,15 +738,34 @@ Replace the fixity declaration for <tt>(:)</tt> by the following comments:
 </pre>
 
 
-<p><li><strong>Page 94, Appendix A, Standard Prelude, class <tt>Enum</tt>.</strong>
+<p><li> [Nov 2001] <strong>Page 94, Appendix A, Standard Prelude, class <tt>Enum</tt>.</strong>
+<ul>
+<li> Before the default methods add:
+<pre>
+       -- NOTE: these default methods only make sense for types
+       --       that map injectively into Int using fromEnum
+       --       and toEnum.
+</pre>
+<li>
 After the default method for <tt>enumFromTo</tt> add
 <pre>
   enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..]
 </pre>
+</ul>
 
 <p><li><strong>Page 95, Appendix A, Standard Prelude, class <tt>Floating</tt>.</strong>
 Add <tt>asin, acos, atan</tt> to the comment giving the list of minimal complete definitions.
 
+<p><li> [Dec 2001] <strong>Page 100, Appendix A, <tt>instance Bounded Char</tt>.</strong>
+<ul>
+<li> Replace the definition of <tt>maxBound</tt> by
+<pre>
+  maxBound = primUnicodeMaxChar
+</pre>
+<li> Import <tt>UnicodePrims( primUnicodeMaxChar )</tt> at the top of the module.
+</ul>
+(This avoids making explicit what the largest character is.)
+
 <p><li> [Apr 2001] <strong>Page 101, Appendix A, <tt>instance Monad IO</tt>.</strong>
 Replace the definition of <tt>fail</tt> in <tt>instance Monad IO</tt> by
 <pre>
@@ -752,8 +868,28 @@ Replace the instances for <tt>Show Int</tt> and <tt>Read Int</tt> with
 </pre>
 The previous definitions (which are simply specifications, remember) failed on minInt.
 
-<p><li> [Nov 2001]  <strong>Page 122, Appendix B.3, Layout</strong>. 
-Replace the third dashed item in the first bullet item by:
+<p><li> [Late Dec 2001] <strong>Page 118, defn of <tt>interact</tt></strong>. 
+Replace the definition of <tt>interact</tt> with the following.
+<pre>
+    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)
+</pre>
+
+<p><li> [Dec 2001]  <strong>Page 122, Appendix B.3, Layout</strong>. 
+<ul>
+<p><li>Replace the first dashed item in the first bullet item by:
+<p>
+"If a <tt>let</tt>, <tt>where</tt>, <tt>do,</tt>, or <tt>of</tt> keyword is not followed by the lexeme <tt>{</tt>, 
+the token "<tt>{n}</tt>" 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."
+<p>
+(This addresses the question of end of file just after a <tt>where</tt>.)
+
+<p><li>Replace the third dashed item in the first bullet item by:
 <p>
 "Where the start of a token does not follow any complete token on the
    same line, this token is preceded by "&lt;n&gt;" where "n"
@@ -762,6 +898,7 @@ Replace the third dashed item in the first bullet item by:
 <p>
 (This addresses the question of empty lines (no layout token) and string-gap tokens
 (no layout token in the middle of them).
+</ul>
 
 <p><li> [Nov 2001]  <strong>Page 122, Appendix B.3, Layout</strong>. 
 In the paragraph following the bullets, add the sentence:
@@ -772,6 +909,29 @@ 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.
 
+<p><li> [Late Dec 2001]  <strong>Page 122,123, Appendix B.3, Layout</strong>. 
+<ul>
+<li>
+On p122, replace "L tokens [0]" by "L tokens []".
+
+<p><li>
+Replace the layout equations on p123 with the following:
+<div align=center><p>
+<table >
+<tr><td>
+     L  (&lt;n&gt;:ts)  (m:ms)   </td><td align=center> = </td><td> <tt>;</tt>  :  (L  ts (m:ms))           </td><td>if  m = n </td></tr><tr><td></td><td align=center> = </td><td> <tt>}</tt>  :  (L  (&lt;n&gt;:ts)  ms)       </td><td> if  n &lt; m </td></tr><tr><td>L  (&lt;n&gt;:ts) ms        </td><td align=center> = </td><td> L  ts ms </td></tr><tr></tr><tr><td>L  ({n}:ts)  (m:ms)   </td><td align=center> = </td><td> <tt>{</tt>  :  (L  ts (n:m:ms))      </td><td> if n &gt; m    (Note  1)</td></tr><tr><td>L  ({n}:ts)  []       </td><td align=center> = </td><td> <tt>{</tt>  :  (L  ts [n])           </td><td> if n &gt; 0    (Note  1)</td></tr><tr><td>L  ({n}:ts)  ms            </td><td align=center> = </td><td> <tt>{</tt>  :  <tt>}</tt>  :   (L  (&lt;n&gt;:ts) ms) </td><td> (Note  2)</td></tr><tr></tr><tr><td>L  (<tt>}</tt>:ts)  (0:ms)     </td><td align=center> = </td><td> <tt>}</tt>  :  (L  ts ms)         </td><td> (Note  3) </td></tr><tr><td>L  (<tt>}</tt>:ts)  ms         </td><td align=center> = </td><td> parse-error             </td><td> (Note  3) </td></tr><tr></tr><tr><td>L  (<tt>{</tt>:ts)  ms         </td><td align=center> = </td><td> <tt>{</tt>  :  (L  ts (0:ms))       </td><td>     (Note  4)</td></tr><tr></tr><tr><td>L  (t:ts)  (m:ms)       </td><td align=center> = </td><td> <tt>}</tt>  :  (L  (t:ts)  ms)      </td><td> if  m /= 0  and  parse-error(t) </td></tr><tr><td></td><td align=center></td><td></td><td> (Note  5) </td></tr><tr><td>L  (t:ts)  ms           </td><td align=center> = </td><td> t  :  (L  ts ms)</td></tr><tr></tr><tr><td>L  []  []             </td><td align=center> = </td><td> []</td></tr><tr><td>L  []  (m:ms)    </td><td align=center> = </td><td> <tt>}</tt>  :  L  []  ms     </td><td> if m /=0   (Note  6)
+</td></tr></table>
+<p>
+
+</div>
+<p><li> Renumber the notes correspondingly.
+</ul>
+(These changes deal with various corner cases, such as empty <tt>where</tt> clauses; 
+order the equations so that they clearly deal completely with the tokens
+"&lt;n&gt;", "{n}", "(", and "}" before dealing with the general case; 
+and ensure
+that the tokens "&lt;n&gt;" and "{n}" are never passed to "parse-error".)
+
 <p><li> [Aug 2001]  <strong>Page 124, Appendix B.3, Layout</strong>. 
 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.)
@@ -787,6 +947,16 @@ with
 by taking only those lines beginning with "<tt>&gt;</tt>", 
 and replacing the leading "<tt>&gt;</tt>" with a space."
 
+<p><li> [Late Dec 2001]  <strong>Page 130, Appendix C, Literate comments</strong>. 
+Final paragraph.  After the phrase "all other lines are comment." add the sentence:
+<p>
+"More precisely:
+<ul>
+<li> Program code begins on the first line following a line that begins <tt>\begin{code}</tt>.
+<li> Program code ends just before a subsequent line that begins <tt>\end{code}</tt> (ignoring
+string literals, of course)."
+</ul>
+
 <p><li> [May 2001]  <strong>Page 132, Appendix D, Specification of Derived Instances</strong>. 
 In numbered item 3, replace 
 ``(all constructors must by nullary)'' with 
@@ -862,7 +1032,41 @@ Replace the definition of <tt>recip</tt> on line 3 by the following
 The effect of this change is to use the "smart constructor", <tt>%</tt>, instead
 doing it by hand.  In particular, an error will be raised if y is zero.
 
-<p><li> [Sept 2001] <strong>Page 13, Section 4.1, Numeric library</strong>.
+<p><li> [Nov 2001] <strong>Page 9, Numeric library</strong>.
+<ul>
+<li> Add <tt>showIntAtBase</tt>, <tt>showHex</tt>, and <tt>showOct</tt> to the export list.
+<li> Add documentation for these functions.
+<li> In the body of the module, replace the definition of <tt>showInt</tt> with the following:
+<pre>
+  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
+</pre>
+(This siginficant change extends the Numeric library so that it can show 
+octal and hexadecimal numbers, just as it can already read them.)
+</ul>
+
+<p><li> [Nov 2001] <strong>Page 13, Section 4.1, Numeric library</strong>.
 <ul>
 <li> Add specifications for the functions exported by the Numeric library.
 
@@ -978,7 +1182,7 @@ Section 6.1.6 of the Language Report.]
 <p><li> <strong>Page 22, Section 6.3; and Page 23, Fig 3</strong>:
 Replace "<tt>map</tt>" by "<tt>fmap</tt>" (two occurrences in 6.3, one in Fig 3).
 
-<p><li> [May 2001] <strong>Page 23, Figure 3</strong>.
+<p><li> [Dec 2001] <strong>Page 23, Figure 3</strong>.
 In the definition of <tt>diag</tt>, delete the guard ``<tt>| l==l' &amp;&amp; u==u'</tt>''.
 (The original intent was presumably to check for a square array, but
  simply makes the definition recursive and hence divergent.)
@@ -989,6 +1193,8 @@ Add an index entry for <tt>nub</tt>.
 <p><li> <strong>Page 29, Section 7.2, second bullet</strong>.  
 Introduce a new bullet just before "<tt>union</tt> is list union".
 
+<p><li> <strong>Page 30, Section 7.3</strong>.  Add a bullet for <tt>insert</tt>.
+
 <p><li> [May 2001] <strong>Page 30, Section 7.4, unfoldr</strong>.
 Replace the first line-and-a-half paragraph with:
 <p>
@@ -1002,6 +1208,16 @@ In some cases, <tt>unfoldr</tt> can undo a <tt>foldr</tt> operation:"
 <p>
 (Followed by the existing displayed equation.)
 
+<p><li> [Apr 2001] <strong>Page 31, Section 7.7, Library List</strong>.
+Add a new subsection "The zip operations" to document zip4, zip5, etc.
+
+<p><li> [Dec 2001] <strong>Page 33, Section 7.8, Library List</strong>.
+Replace the definition of <tt>unionBy</tt> by the following:
+<pre>
+    unionBy eq xs ys =  xs ++ deleteFirstsBy eq (nubBy eq ys) xs
+</pre>
+(This is a simpler definition to understand.)
+
 <p><li> [Apr 2001] <strong>Page 34, Section 7.8, Library List</strong>.
 Replace the definition of <tt>partition</tt> by
 <pre>
@@ -1032,6 +1248,12 @@ Replace the definitions of <tt>maximumBy</tt> and <tt>minimumBy</tt> by the foll
 <strong>NOTE:</strong> this is a semantic change, but it makes the definitions
 consistent with the other "By" functions, and with the signatures given on page 28.
 
+<p><li> [Dec 2001] <strong>Page 41, Sections 9, Character utilities</strong>.
+Add an explanation of <tt>lexLitChar</tt>, and an example.
+
+<p><li><strong>Page 48, Sections 10.3, Monads</strong>.
+In the definition of <tt>listFile</tt> replace "<tt>openFile</tt>" by "<tt>readFile</tt>".
+
 <p><li><strong>Page 54, Sections 11, 12, 13</strong>.
 Replace "<tt>isIllegalOperationError</tt>" with "<tt>isIllegalOperation</tt>" throughout.
 Namely:
@@ -1127,6 +1349,16 @@ the module header, and from the module body.
 in the module header.
 </ul>
 
+<p><li> [Dec 2001] <strong>Page 65, Directory functions.</strong>
+To paragraph 4, the "Error reporting" paragraph for <tt>createDirectory</tt>, append the
+final clause "; or <tt>isDoesNotExistError</tt> if the new directory's parent does not exist".
+
+<p><li> [Nov 2001] <strong>Page 66, Directory functions.</strong>
+Add to the paragraph "Computation <tt>getDirectoryContents</tt> dir returns a list of all entries
+in dir." the following extra sentence:
+<p>
+"Each entry in the returned list is named relative to the directory dir, not as an absolute path."
+
 <p><li> [Apr 2001] <strong>Page 78, Section 16, The <tt>CPUTime</tt> library</strong>.
 Add <tt>cpuTimePrecision</tt> to the export list.
 
index e7ff38d..ead6e91 100644 (file)
@@ -160,12 +160,13 @@ subArray bnds = ixmap bnds (\i->i)
 
 -- A row of a matrix
 row :: (Ix a, Ix b) => a -> Array (a,b) c -> Array b c
-row i x = ixmap (l',u') (\j->(i,j)) x where ((l,l'),(u,u')) = bounds x
+row i x = ixmap (l',u') (\j->(i,j)) x where ((_,l'),(_,u')) = bounds x
 
--- Diagonal of a square        matrix
+-- Diagonal of a matrix (assumed to be square)
 diag :: (Ix a) => Array (a,a) b -> Array a b
 diag x = ixmap (l,u) (\i->(i,i)) x
-        where ((l,l'),(u,u')) | l == l' && u == u'  = bounds x
+       where 
+         ((l,_),(u,_)) = bounds x
 
 -- Projection of first components of an array of pairs
 firstArray :: (Ix a) => Array a (b,c) -> Array a b
index dc8832b..a9db06b 100644 (file)
@@ -66,7 +66,17 @@ range.
 
 The function @showLitChar@ converts a character to a string using
 only printable characters, using Haskell source-language escape conventions.
-The function @readLitChar@ does the reverse.
+The function @lexLitChar@ does the reverse, returning the sequence of characters 
+that encode the character.
+The function @readLitChar@ does the same, but in addition converts the 
+to the character that it encodes.  For example:
+\bprog
+@
+  showLitChar '\n' s       =  "\\n" ++ s
+  lexLitChar  "\\nHello"   =  [("\\n", "Hello")]
+  readLitChar "\\nHello"   =  [("\n", "Hello")]
+@
+\eprog
 
 Function @toUpper@ converts a letter to the corresponding
 upper-case letter, leaving any other character unchanged.  Any
index 7244b4e..d15e9b9 100644 (file)
@@ -10,9 +10,9 @@ module Char (
     Char, String
     ) where
 
-import Array  -- used for character name table.
+import Array         -- Used for character name table.
 import Numeric (readDec, readOct, lexDigits, readHex)
-import UnicodePrims  -- source of primitive Unicode functions.
+import UnicodePrims  -- Source of primitive Unicode functions.
 
 -- Character-testing operations
 isAscii, isControl, isPrint, isSpace, isUpper, isLower,
index 6327f1b..d70b192 100644 (file)
@@ -1,4 +1,4 @@
-module IO where
+module IO {- export list omitted -} where
 
 -- Just provide an implementation of the system-indendent
 -- actions that IO exports.
index 5192c9e..0300b1b 100644 (file)
@@ -14,7 +14,7 @@ module List (
     unzip4, unzip5, unzip6, unzip7, unfoldr,
 
     -- ...and what the Prelude exports
-    []((:), []),
+    -- []((:), []),    -- This is built-in syntax
     map, (++), concat, filter,
     head, last, tail, init, null, length, (!!),
     foldl, foldl1, scanl, scanl1, foldr, foldr1, scanr, scanr1,
@@ -69,7 +69,7 @@ union                   :: Eq a => [a] -> [a] -> [a]
 union                   =  unionBy (==)    
 
 unionBy                 :: (a -> a -> Bool) -> [a] -> [a] -> [a]
-unionBy eq xs ys        =  xs ++ foldl (flip (deleteBy eq)) (nubBy eq ys) xs
+unionBy eq xs ys        =  xs ++ deleteFirstsBy eq (nubBy eq ys) xs
 
 intersect               :: Eq a => [a] -> [a] -> [a]
 intersect               =  intersectBy (==)
@@ -83,15 +83,15 @@ intersperse sep [x]     =  [x]
 intersperse sep (x:xs)  =  x : sep : intersperse sep xs
 
 -- transpose is lazy in both rows and columns,
---      and works for non-rectangular 'matrices'
+--       and works for non-rectangular 'matrices'
 -- For example, transpose [[1,2],[3,4,5],[]]  =  [[1,3],[2,4],[5]]
 -- Note that [h | (h:t) <- xss] is not the same as (map head xss)
---     because the former discards empty sublists inside xss
+--      because the former discards empty sublists inside xss
 transpose                :: [[a]] -> [[a]]
-transpose []            = []
+transpose []             = []
 transpose ([]     : xss) = transpose xss
 transpose ((x:xs) : xss) = (x : [h | (h:t) <- xss]) : 
-                          transpose (xs : [t | (h:t) <- xss])
+                           transpose (xs : [t | (h:t) <- xss])
 
 partition               :: (a -> Bool) -> [a] -> ([a],[a])
 partition p xs          =  (filter p xs, filter (not . p) xs)
@@ -139,10 +139,10 @@ mapAccumR f s (x:xs)    =  (s'', y:ys)
                            where (s'',y ) = f s' x
                                  (s', ys) = mapAccumR f s xs
 
-unfoldr                        :: (b -> Maybe (a,b)) -> b -> [a]
-unfoldr f b            = case f b of
-                               Nothing    -> []
-                               Just (a,b) -> a : unfoldr f b
+unfoldr                 :: (b -> Maybe (a,b)) -> b -> [a]
+unfoldr f b             = case f b of
+                                Nothing    -> []
+                                Just (a,b) -> a : unfoldr f b
 
 sort                    :: (Ord a) => [a] -> [a]
 sort                    =  sortBy compare
@@ -150,8 +150,8 @@ sort                    =  sortBy compare
 sortBy                  :: (a -> a -> Ordering) -> [a] -> [a]
 sortBy cmp              =  foldr (insertBy cmp) []
 
-insert                 :: (Ord a) => a -> [a] -> [a]
-insert                 = insertBy compare
+insert                  :: (Ord a) => a -> [a] -> [a]
+insert                  = insertBy compare
 
 insertBy                :: (a -> a -> Ordering) -> a -> [a] -> [a]
 insertBy cmp x []       =  [x]
@@ -163,18 +163,18 @@ insertBy cmp x ys@(y:ys')
 maximumBy               :: (a -> a -> Ordering) -> [a] -> a
 maximumBy cmp []        =  error "List.maximumBy: empty list"
 maximumBy cmp xs        =  foldl1 max xs
-                       where
-                          max x y = case cmp x y of
-                                       GT -> x
-                                       _  -> y
+                        where
+                           max x y = case cmp x y of
+                                        GT -> x
+                                        _  -> y
 
 minimumBy               :: (a -> a -> Ordering) -> [a] -> a
 minimumBy cmp []        =  error "List.minimumBy: empty list"
 minimumBy cmp xs        =  foldl1 min xs
-                       where
-                          min x y = case cmp x y of
-                                       GT -> y
-                                       _  -> x
+                        where
+                           min x y = case cmp x y of
+                                        GT -> y
+                                        _  -> x
 
 genericLength           :: (Integral a) => [b] -> a
 genericLength []        =  0
index c61a2b9..918f3c6 100644 (file)
@@ -1,5 +1,6 @@
 module Numeric(fromRat,
-               showSigned, showInt,
+               showSigned, showIntAtBase,
+               showInt, showOct, showHex,
                readSigned, readInt,
                readDec, readOct, readHex, 
                floatToDigits,
@@ -84,18 +85,29 @@ integerLogBase b i =
 
 -- Misc utilities to show integers and floats 
 
-showSigned    :: Real a => (a -> ShowS) -> Int -> a -> ShowS
-showSigned showPos p x | x < 0 = showParen (p > 6)
-                                           (showChar '-' . showPos (-x))
-                       | otherwise = showPos x
-
--- showInt is used for positive numbers only
-showInt    :: Integral a => a -> ShowS
-showInt n r | n < 0 = error "Numeric.showInt: can't show negative numbers"
-            | otherwise =
-              let (n',d) = quotRem n 10
-                  r'     = toEnum (fromEnum '0' + fromIntegral d) : r
-              in  if n' == 0 then r' else showInt n' r'
+showSigned :: Real a => (a -> ShowS) -> Int -> a -> ShowS
+showSigned showPos p x 
+  | x < 0     = showParen (p > 6) (showChar '-' . showPos (-x))
+  | otherwise = showPos x
+
+-- showInt, showOct, showHex are used for positive numbers only
+showInt, showOct, showHex :: Integral a => a -> ShowS
+showOct = showIntAtBase  8 intToDigit
+showInt = showIntAtBase 10 intToDigit
+showHex = showIntAtBase 16 intToDigit
+
+showIntAtBase :: Integral a 
+             => a              -- base
+             -> (Int -> Char)  -- digit to char
+             -> a              -- number to show
+             -> ShowS
+showIntAtBase base intToDig n rest
+  | n < 0     = error "Numeric.showIntAtBase: can't show negative numbers"
+  | n' == 0   = rest'
+  | otherwise = showIntAtBase base intToDig n' rest'
+  where
+    (n',d) = quotRem n base
+    rest'  = intToDig (fromIntegral d) : rest
 
 
 readSigned :: (Real a) => ReadS a -> ReadS a
index 76a7c02..6de782c 100644 (file)
@@ -1,4 +1,4 @@
-`%**<title>The Haskell 98 Library Report: Directory functions</title>
+%**<title>The Haskell 98 Library Report: Directory functions</title>
 %**~header
 
 %% Other useful functions from SML 96 include modification time
@@ -42,10 +42,11 @@ Computation @createDirectory@~"dir" creates a new directory "dir" which is
 initially empty, or as near to empty as the operating system allows.
 \index{making directories}
 
-{\em Error~reporting}:
-the @createDirectory@ computation may fail with:
+{\em Error~reporting}.
+The @createDirectory@ computation may fail with:
 @isPermissionError@ if the user is not permitted to create the directory;
-@isAlreadyExistsError@ if the directory already exists.
+@isAlreadyExistsError@ if the directory already exists; or @isDoesNotExistError@ if
+the new directory's parent does not exist.
 
 Computation @removeDirectory@~"dir" removes an existing directory
 "dir"\index{deleting directories}\index{removing directories}.  The
@@ -63,8 +64,8 @@ files}\index{removing files}. The implementation may specify additional
 constraints which must be satisfied before a file can be removed (for instance, the
 file may not be in use by other processes).
 
-{\em Error~reporting}:
-the @removeDirectory@ and @removeFile@ computations may fail with:
+{\em Error~reporting}.
+The @removeDirectory@ and @removeFile@ computations may fail with:
 @isPermissionError@ if the user is not permitted to remove the file/directory;
 or @isDoesNotExistError@ if the file/directory does not exist.
 
@@ -86,21 +87,22 @@ implementation need not support renaming files in all situations
 (for instance, renaming across different physical devices), but the constraints must be
 documented.
 
-{\em Error~reporting}:
-the @renameDirectory@ and @renameFile@ computations may fail with:
+{\em Error~reporting}.
+The @renameDirectory@ and @renameFile@ computations may fail with:
 @isPermissionError@ if the user is not permitted to rename the file/directory,
 or if either argument to @renameFile@ is a directory;
 or @isDoesNotExistError@ if the file/directory does not exist.
 
 Computation @getDirectoryContents@~"dir" returns a list of {\em all} entries
 in "dir"\index{reading a directory}.
+Each entry in the returned list is named relative to the directory "dir", not as an absolute path.
 
 If the operating system has a notion of current directories,
 @getCurrentDirectory@ returns an absolute path to the
 current directory of the calling process\index{current directory}.
 
-{\em Error~reporting}:
-the @getDirectoryContents@ and @getCurrentDirectory@ computations may fail with:
+{\em Error~reporting}.
+The @getDirectoryContents@ and @getCurrentDirectory@ computations may fail with:
 @isPermissionError@ if the user is not permitted to access the directory;
 or @isDoesNotExistError@ if the directory does not exist.
 
@@ -108,8 +110,8 @@ If the operating system has a notion of current directories,
 @setCurrentDirectory@~"dir" changes the current directory of the
 calling process to "dir"\index{changing the directory}\index{setting the directory}.
 
-{\em Error~reporting}:
-the @setCurrentDirectory@ computation may fail with:
+{\em Error~reporting}.
+@setCurrentDirectory@ may fail with:
 @isPermissionError@ if the user is not permitted to change directory
 to that specified;
 or @isDoesNotExistError@ if the directory does not exist.
@@ -140,11 +142,11 @@ if the argument file exists and is not a directory, and @False@ otherwise.
 The @getModificationTime@ operation returns the
 clock time at which the file/directory was last modified.
 
-{\em Error~reporting}:
-the @get(set)Permissions@,
+{\em Error~reporting}.
+@get(set)Permissions@,
 @doesFile(Directory)Exist@,
 and @getModificationTime@
-computations may fail with:
+may fail with:
 @isPermissionError@ if the user is not permitted to access
 the appropriate information;
 or @isDoesNotExistError@ if the file/directory does not exist.
index 8d70f3d..3722821 100644 (file)
@@ -4,7 +4,7 @@ module Char (
     digitToInt, intToDigit,
     toUpper, toLower,
     ord, chr,
-    readLitChar, showLitChar, lexLitChar
+    readLitChar, showLitChar, lexLitChar,
 
        -- ...and what the Prelude exports
     Char, String
index a9c7d64..2e2b1d8 100644 (file)
@@ -14,7 +14,7 @@ module IO (
     isFullError, isEOFError,
     isIllegalOperation, isPermissionError, isUserError, 
     ioeGetErrorString, ioeGetHandle, ioeGetFileName,
-    try, bracket, bracket_
+    try, bracket, bracket_,
 
     -- ...and what the Prelude exports
     IO, FilePath, IOError, ioError, userError, catch, interact,
index 615ae98..df18dd3 100644 (file)
@@ -14,7 +14,7 @@ module List (
     unzip4, unzip5, unzip6, unzip7, unfoldr,
 
     -- ...and what the Prelude exports
-    []((:), []),
+    -- []((:), []),    -- This is built-in syntax
     map, (++), concat, filter,
     head, last, tail, init, null, length, (!!),
     foldl, foldl1, scanl, scanl1, foldr, foldr1, scanr, scanr1,
index 82c9426..9cd98d9 100644 (file)
@@ -1,5 +1,6 @@
 module Numeric(fromRat,
-               showSigned, showInt,
+               showSigned, showIntAtBase,
+               showInt, showOct, showHex,
                readSigned, readInt,
                readDec, readOct, readHex, 
                floatToDigits,
@@ -7,8 +8,13 @@ module Numeric(fromRat,
                readFloat, lexDigits) where
 
 fromRat        :: (RealFloat a) => Rational -> a
+
 showSigned     :: (Real a) => (a -> ShowS) -> Int -> a -> ShowS
+showIntAtBase  :: Integral a => a -> (Int -> Char) -> a -> ShowS
 showInt        :: Integral a => a -> ShowS
+showOct        :: Integral a => a -> ShowS
+showHex        :: Integral a => a -> ShowS
+
 readSigned     :: (Real a) => ReadS a -> ReadS a
 readInt        :: (Integral a) =>
                     a -> (Char -> Bool) -> (Char -> Int) -> ReadS a
index db3f057..d1f589d 100644 (file)
@@ -33,7 +33,7 @@ style=article
 ~back=<a href="~prev.html">back</a>
 ~nxt=<a href="~next.html">next</a>
 ~contents=<a href="libindex.html">contents</a>
-~foot=<br><font size=2>October 2001</font>
+~foot=<br><font size=2>December 2001</font>
 ~footer=<hr>~id~top | ~back | ~nxt | ~contents ~foot
 ~sfooter=<hr>~id~top | back | ~nxt | ~contents ~foot
 ~efooter=<hr>~id~top | ~back | next | ~contents ~foot
index f1b26c7..62c32c4 100644 (file)
@@ -7,7 +7,7 @@
 <img src="h98-libs.gif" alt="Haskell 98 Libraries">
 
 <h3 align="center">Standard Libraries for Haskell 98</h3>
-<h3 align="center">Revised: October 2001</h3>
+<h3 align="center">Revised: December 2001</h3>
 </div>
 <hr>
 <h3>Table of Contents</h3>
index a073a23..db48fb3 100644 (file)
@@ -92,7 +92,6 @@ computation.  This is similar to try-catch-finally in Java.
 % Inline the code here since there's no other functions in IO that
 % are not primitive.
 
-\inputHS{code/IO}
 
 
 \subsection{Files and Handles}
@@ -181,7 +180,7 @@ or once the entire contents of the handle has been read.
 Once a semi-closed handle becomes closed, the contents of the
 associated list becomes fixed.  The contents of this final list is
 only partially specified: it will contain at least all the items of
-the stream that were evalutated prior to the handle becoming closed.
+the stream that were evaluated prior to the handle becoming closed.
 
 Any I/O errors encountered while a handle is semi-closed are simply
 discarded.
@@ -559,8 +558,8 @@ main = do
          x2 <- readNum                          
          putStr  ("Their sum is " ++ show (x1+x2) ++ "\n")
        where readNum :: IO Integer
-               -- Need a type signature for 
-               -- readLn to avoid ambiguity
+               -- Providing a type signature avoids reliance on
+               -- the defaulting rule to fix the type of x1,x2
              readNum = readLn
 @
 \eprog
@@ -575,6 +574,7 @@ Note that exactly two arguments must be supplied to the program.
 @
 import IO
 import System
+import Char( toUpper )
 
 main = do 
          [f1,f2] <- getArgs
@@ -598,6 +598,7 @@ An equivalent but much shorter version, using string I/O is:
 \bprog
 @
 import System
+import Char( toUpper )
 
 main = do
          [f1,f2] <- getArgs
@@ -616,5 +617,8 @@ main = do
 % the @~@, a class error would occur because there is no instance of
 % @IO@ for class @MonadZero@.
 
+\subsection{Library @IO@}
+
+\inputHS{code/IO}
 
 %**~footer
index 0c0560e..8161174 100644 (file)
@@ -1,5 +1,5 @@
 %
-% $Header: /home/cvs/root/haskell-report/libraries/library.verb,v 1.11 2001/10/02 09:09:26 simonpj Exp $
+% $Header: /home/cvs/root/haskell-report/libraries/library.verb,v 1.12 2001/12/21 16:00:22 simonpj Exp $
 %
 % NOTE:--------------------------------------------------------------
 % The formatting of this report and the ``new font selection scheme''
 %\newcommand{\subsubsubsection}[1]{\par\noindent{\it #1}}
 \newcommand{\subsubsubsection}{\subsubsection*}
 
-%\sloppy
+\sloppy
 
 % a few hyphenation patterns, anyone?
 \hyphenation{da-ta-type da-ta-types}
 {\Large\bf for the} \\[.1in]
 {\huge\bf Haskell 98} \\[.3in]
 {\LARGE\bf Programming Language} \\[.3in]
-{\large\bf Revised: October 2001}
+{\large\bf Revised: December 2001}
 \end{center}
 
 \vspace{.15in}
@@ -456,7 +456,7 @@ Copyright (c) Simon Peyton Jones.
 
 {\em The authors intend this Report to belong to the entire Haskell
 community, and so we grant permission to copy and distribute it for
-any purpose, provided that it is reproduced in its entireity,
+any purpose, provided that it is reproduced in its entirety,
 including this Notice. Modified versions of this Report may also be
 copied and distributed for any purpose, provided that the modified
 version is clearly presented as such, and that it does not claim to be
index 0012ec4..018e829 100644 (file)
@@ -13,18 +13,20 @@ This library defines some lesser-used operations over lists.
 
 \subsection{Indexing lists}
 
-Function @elemIndex val list@\indextt{elemIndex} returns the index of
+\begin{itemize}
+\item @elemIndex val list@\indextt{elemIndex} returns the index of
 the first occurrence, if any, of @val@  
 in @list@ as @Just index@.  @Nothing@ is returned if @not (val `elem` list)@.
 
-Function @elemIndices val list@\indextt{elemIndices} returns an
+\item @elemIndices val list@\indextt{elemIndices} returns an
 in-order list of indices, giving the occurrences of @val@ in @list@.
 
-Function @find@\indextt{find} 
+\item  @find@\indextt{find} 
 returns the first element of a list that satisfies a predicate,
 or Nothing, if there is no such element.
 @findIndex@ returns the corresponding index.
 @findIndices@ returns a list of all such indices.
+\end{itemize}
 
 \subsection{``Set'' operations}
 
@@ -109,14 +111,18 @@ predicate, respectively; i.e.,
 \eprog
 
 \item
-@sort@/@sortBy@\indextt{sort}\indextt{sortBy} 
+@sort@\indextt{sort}
 implement a stable sorting algorithm, here specified
 in terms of the @insertBy@ function, which inserts objects into a list
 according to the specified ordering relation.
 
 \item
+@insert@\indextt{insert}
+inserts a new element into an {\em ordered} list (arranged in increasing order).
+
+\item
 @group@\indextt{group} splits its list argument into a list of lists of equal, adjacent
-elements. For exmaple
+elements. For example
 \bprog
 @
   group "Mississippi" == ["M","i","ss","i","ss","i","pp","i"]
@@ -209,8 +215,21 @@ function replaces an @Ord@ context by a binary predicate, the
 predicate is assumed to define a total ordering.
 
 The ``@By@'' variants are as follows:
-@nubBy@, @deleteBy@, @unionBy@, @intersectBy@, @groupBy@,
-@sortBy@, @insertBy@, @maximumBy@, @minimumBy@.  The library does not
+@nubBy@, @deleteBy@, @deleteFirstsBy@ (the "@By@" variant of @\\@),
+@unionBy@, @intersectBy@, @groupBy@,
+@sortBy@, @insertBy@, @maximumBy@, @minimumBy@.  
+\indextt{nubBy} 
+\indextt{deleteBy} 
+\indextt{deleteFirstsBy} 
+\indextt{unionBy} 
+\indextt{intersectBy} 
+\indextt{groupBy} 
+\indextt{sortBy} 
+\indextt{insertBy} 
+\indextt{maximumBy} 
+\indextt{minimumBy} 
+
+The library does not
 provide @elemBy@, because @any (eq x)@ does the same job as @elemBy eq x@ would.
 A handful of overloaded functions (@elemIndex@, @elemIndices@, @isPrefixOf@, @isSuffixOf@)
 were not considered important enough to have ``@By@'' variants.
@@ -234,9 +253,16 @@ is a generalised verion of @length@.
 
 The ``@generic@'' operations are as follows:
 @genericLength@, @genericTake@, @genericDrop@,
-    @genericSplitAt@, @genericIndex@, @genericReplicate@.
+    @genericSplitAt@, @genericIndex@ (the generic version of @!!@), @genericReplicate@.
+
 
+\subsection{Further ``@zip@'' operations}
 
+The Prelude provides @zip@, @zip3@, @unzip@, @unzip3@, @zipWith@, and @zipWith3@.
+The List library provides these same three operations for 4, 5, 6, and 7 arguments.
+\indextt{zip4}
+\indextt{unzip4}
+\indextt{zipWith4}
 
 \clearpage
 \subsection{Library {\tt List}}
index 737cbc2..a0bb564 100644 (file)
@@ -20,8 +20,8 @@ A postfix ``@M@'' always stands for a function in the Kleisli category:
 So, for example,
 \bprog
 @
-  filter  ::              (a ->   Bool) -> [a] ->   [a]
-  filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
+  filter  ::            (a ->   Bool) -> [a] ->   [a]
+  filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]
 @
 \eprog
 
@@ -49,7 +49,7 @@ Thus, for example:
 The @MonadPlus@ class is defined as follows:
 \bprog
 @
-class  (Monad m) => MonadPlus m  where
+class  Monad m => MonadPlus m  where
     mzero  :: m a
     mplus  :: m a -> m a -> m a
 @
@@ -90,7 +90,7 @@ each line with its line number,
 @
 listFile :: String -> IO ()
 listFile nm =
-  do cts <- openFile nm
+  do cts <- readFile nm
      zipWithM_ (\i line -> do putStr (show i); putStr ": "; putStrLn line)
                [1..]
                (lines cts)
index db5b6a4..4c05521 100644 (file)
@@ -25,7 +25,12 @@ possibly-negative @Real@ value of type @a@ to a string.  In the call "(@showSign
 "val" is the value to show, "prec" is the precedence of the enclosing context, and "show" is
 a function that can show unsigned values.
 
-\item @showInt :: Integral a => a -> ShowS@ \\ shows {\em unsigned} @Integral@ values of type @a@.
+\item @showIntAtBase :: Integral a => a -> (Int -> Char) -> a -> ShowS@ \\
+shows a {\em non-negative} @Integral@ number using the base specified by the first argument,
+and the character representation specified by the second.
+
+\item @showInt, showOct, showHex :: Integral a => a -> ShowS@ \\ 
+show {\em non-negative} @Integral@ numbers in base 10, 8, and 16 respectively.
 
 \item 
 @showFFloat, showEFloat, showGFloat@ \\
@@ -71,6 +76,8 @@ each read an unsigned number, in decimal, octal, and hexadecimal notation respec
 In the hexadecimal case, both upper or lower case letters are allowed.
 \item @lexDigits :: ReadS String@ reads a non-empty string of decimal digits.
 \end{itemize}
+(NB: @readInt@ is the ``dual'' of @showIntAtBase@, and @readDec@ is the ``dual'' of @showInt@.
+The inconsistent naming is a historical accident.)
 
 \subsection{Miscellaneous}
 
index 86242be..b73507f 100644 (file)
@@ -48,7 +48,7 @@ the generator.
 
 It is required that:
 \begin{itemize}
-\item If $(a,b) ~=~ @genRange@~ g$, then $a \leq b$.
+\item If $(a,b) ~=~ @genRange@~ g$, then $a < b$.
 \item $@genRange@~\bot ~\neq~ \bot$.  
 \end{itemize}
 The second condition ensures that @genRange@ cannot examine its
index 94c748c..445c1e7 100644 (file)
@@ -41,7 +41,8 @@ module Prelude (
     seq, ($!)
   ) where
 
-import PreludeBuiltin  -- Contains all `prim' values
+import PreludeBuiltin                      -- Contains all `prim' values
+import UnicodePrims( primUnicodeMaxChar )  -- Unicode primitives
 import PreludeList
 import PreludeText
 import PreludeIO
@@ -68,12 +69,12 @@ infixr 0  $, $!, `seq`
 -- Equality and Ordered classes
 
 class  Eq a  where
-    (==), (/=)       :: a -> a -> Bool
+    (==), (/=) :: a -> a -> Bool
 
         -- Minimal complete definition:
         --      (==) or (/=)
-    x /= y           =  not (x == y)
-    x == y           =  not (x /= y)
+    x /= y     =  not (x == y)
+    x == y     =  not (x /= y)
 
 class  (Eq a) => Ord a  where
     compare              :: a -> a -> Ordering
@@ -114,11 +115,15 @@ class  Enum a  where
 
         -- 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, ..]
+    enumFromThen x y =  map toEnum [fromEnum x, fromEnum y ..]
     enumFromThenTo x y z = 
                         map toEnum [fromEnum x, fromEnum y .. fromEnum z]
 
@@ -323,11 +328,10 @@ f =<< x          =  x >>= f
 -- Trivial type
 
 data  ()  =  ()  deriving (Eq, Ord, Enum, Bounded)
+       -- Not legal Haskell; for illustration only
 
 -- Function type
 
-data a -> b  -- No constructor for functions is exported.
-
 -- identity function
 id               :: a -> a
 id x             =  x
@@ -376,7 +380,7 @@ otherwise        =  True
 
 -- Character type
 
-data Char = ... 'a' | 'b' ... -- 2^16 unicode values
+data Char = ... 'a' | 'b' ... -- Unicode values
 
 instance  Eq Char  where
     c == c'          =  fromEnum c == fromEnum c'
@@ -390,12 +394,12 @@ instance  Enum Char  where
     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
+                            lastChar | c' < c    = minBound
+                                     | otherwise = maxBound
 
 instance  Bounded Char  where
-    minBound            =  '\0'
-    maxBound            =  '\xffff'
+    minBound  =  '\0'
+    maxBound  =  primUnicodeMaxChar
 
 type  String = [Char]
 
@@ -428,7 +432,7 @@ either f g (Right y) =  g y
 
 -- IO type
 
-data  IO a  -- abstract
+data IO a = ...        -- abstract
 
 instance  Functor IO where
    fmap f x           =  x >>= (return . f)
@@ -526,9 +530,8 @@ numericEnumFromThenTo n n' m = takeWhile p (numericEnumFromThen n n')
 
 -- Lists
 
--- This data declaration is not legal Haskell
--- but it indicates the idea
 data  [a]  =  [] | a : [a]  deriving (Eq, Ord)
+       -- Not legal Haskell; for illustration only
 
 instance Functor [] where
     fmap = map
@@ -542,7 +545,7 @@ instance  Monad []  where
 
 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.)
index 71bc577..f0c8f08 100644 (file)
@@ -15,52 +15,55 @@ 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)
+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 ()
-interact f       =  do s <- getContents
-                       putStr (f s)
-
-readFile         :: FilePath -> IO String
-readFile         =  primReadFile
-
-writeFile        :: FilePath -> String -> IO ()
-writeFile        =  primWriteFile
-
-appendFile       :: FilePath -> String -> IO ()
-appendFile       =  primAppendFile
+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
@@ -69,7 +72,7 @@ readIO s =  case [x | (x,t) <- reads s, ("","") <- lex t] of
               []  -> 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
+readLn :: Read a => IO a
+readLn =  do l <- getLine
+             r <- readIO l
+             return r
index daf6c89..8ceafbe 100644 (file)
@@ -1,14 +1,14 @@
 -- Standard list functions
 
 module PreludeList (
-    map, (++), filter, concat,
+    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, concatMap, 
+    sum, product, maximum, minimum, 
     zip, zip3, zipWith, zipWith3, unzip, unzip3)
   where
 
@@ -28,13 +28,15 @@ map f (x:xs) = f x : map f xs
 (x:xs) ++ ys = x : (xs ++ ys)
 
 filter :: (a -> Bool) -> [a] -> [a]
-filter p [] = []
+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
@@ -45,15 +47,15 @@ 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"
 
-tail             :: [a] -> [a]
-tail (_:xs)      =  xs
-tail []          =  error "Prelude.tail: empty list"
-
 init             :: [a] -> [a]
 init [x]         =  []
 init (x:xs)      =  x : init xs
@@ -264,9 +266,6 @@ maximum xs       =  foldl1 max xs
 minimum []       =  error "Prelude.minimum: empty list"
 minimum xs       =  foldl1 min xs
 
-concatMap        :: (a -> [b]) -> [a] -> [b]
-concatMap f      =  concat . map f
-
 -- 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
index 944950d..9fb7633 100644 (file)
@@ -6,7 +6,7 @@ module PreludeText (
     showChar, showString, readParen, showParen ) where
 
 -- The instances of Read and Show for
---     Bool, Char, Maybe, Either, Ordering
+--      Bool, Char, Maybe, Either, Ordering
 -- are done via "deriving" clauses in Prelude.hs
 
 import Char(isSpace, isAlpha, isDigit, isAlphaNum,
@@ -22,8 +22,8 @@ class  Read a  where
     readsPrec        :: Int -> ReadS a
     readList         :: ReadS [a]
 
-       -- Minimal complete definition:
-       --      readsPrec
+        -- Minimal complete definition:
+        --      readsPrec
     readList         = readParen False (\r -> [pr | ("[",s)  <- lex r,
                                                     pr       <- readl s])
                        where readl  s = [([],t)   | ("]",t)  <- lex s] ++
@@ -36,14 +36,14 @@ class  Read a  where
 
 class  Show a  where
     showsPrec        :: Int -> a -> ShowS
-    show            :: a -> String 
+    show             :: a -> String 
     showList         :: [a] -> ShowS
 
-       -- Mimimal complete definition:
-       --      show or showsPrec
+        -- Mimimal complete definition:
+        --      show or showsPrec
     showsPrec _ x s   = show x ++ s
 
-    show x           = showsPrec 0 x ""
+    show x            = showsPrec 0 x ""
 
     showList []       = showString "[]"
     showList (x:xs)   = showChar '[' . shows x . showl xs
@@ -113,7 +113,7 @@ lex (c:s) | isSingle c = [([c],s)]
           | otherwise  = []    -- bad character
              where
               isSingle c =  c `elem` ",;()[]{}_`"
-             isSym c    =  c `elem` "!@#$%&*+./<=>?\\^|:-~"
+              isSym c    =  c `elem` "!@#$%&*+./<=>?\\^|:-~"
               isIdChar c =  isAlphaNum c || c `elem` "_'"
 
               lexFracExp ('.':c:cs) | isDigit c
@@ -129,13 +129,13 @@ lex (c:s) | isSingle c = [([c],s)]
 
 instance  Show Int  where
     showsPrec n = showsPrec n . toInteger
-       -- Converting to Integer avoids
-       -- possible difficulty with minInt
+        -- 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
+        -- Reading at the Integer type avoids
+        -- possible difficulty with minInt
 
 instance  Show Integer  where
     showsPrec           = showSigned showInt
index e87ca07..a570bcb 100644 (file)
@@ -1,5 +1,5 @@
 %
-% $Header: /home/cvs/root/haskell-report/report/basic.verb,v 1.10 2001/11/02 16:26:48 simonpj Exp $
+% $Header: /home/cvs/root/haskell-report/report/basic.verb,v 1.11 2001/12/21 16:00:24 simonpj Exp $
 %
 %**<title>The Haskell 98 Report: Basic Types and Classes</title>
 %*section 6
@@ -274,29 +274,12 @@ are instances of these classes.
 \end{figure}
 
 Default class method declarations (Section~\ref{classes}) are provided
-for many of the methods in standard classes.  For example, the declaration
-of class @Eq@ is:
-\bprog
-@
-  class  Eq a  where
-        (==), (/=)  ::  a -> a -> Bool
-
-        x /= y  = not (x == y)
-        x == y  = not (x /= y)
-@
-\eprog
-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.
-
-A comment with each @class@ declaration in Appendix~\ref{stdprelude} specifies
-the smallest collection of method definitions that, 
-together with the default declarations,
-provide a definition for all the class methods.
-If there is no such comment, then all class methods must
-be given to fully specify an instance.
+for many of the methods in standard classes.  A comment with each
+@class@ declaration in Appendix~\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}
@@ -316,6 +299,12 @@ 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{<}
@@ -360,10 +349,9 @@ The @Ordering@ datatype
 allows a single comparison to determine the precise ordering of two
 objects.
 
-%      Either all subsections should have this info, or none.
-% The defaults allow a user to create an @Ord@ instance 
-% either with a type-specific @compare@ function or with type-specific
-% @==@ and @<=@ functions.
+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}
@@ -479,7 +467,7 @@ sequences (Section~\ref{arithmetic-sequences}).
 Instances of @Enum@ may be derived for any enumeration type (types
 whose constructors have no fields); see Appendix~\ref{derived-appendix}.
 
-For any type that is an instance of class @Bounded@, the following
+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
@@ -496,10 +484,8 @@ an implicit bound, thus:
   enumFrom     x   = enumFromTo     x maxBound
   enumFromThen x y = enumFromThenTo x y bound
     where
-      bound = if fromEnum y >= fromEnum x then
-                 maxBound
-              else
-                 minBound
+      bound | fromEnum y >= fromEnum x = maxBound
+            | otherwise                = minBound
 @
 \eprog
 \end{itemize}
@@ -520,7 +506,7 @@ 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.
+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@.
 
@@ -529,7 +515,7 @@ 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@,@...@]@",
+\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.
 
@@ -537,7 +523,7 @@ If the increment is zero, all the list elements are the same.
 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" 
+\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
@@ -549,7 +535,6 @@ 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".
-@fromEnum@ and @toEnum@ convert between the type and @Int@.
 
 For all four of these Prelude numeric types, all of the @enumFrom@ 
 family of functions are strict in all their arguments.
@@ -923,9 +908,11 @@ 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
-integer that divides both "x" and "y".  @lcm@\indextt{lcm} "x" "y"
-is the smallest positive integer that both "x" and "y" divide.
+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}
index 0145b0f..955ff6c 100644 (file)
@@ -1,5 +1,5 @@
 %
-% $Header: /home/cvs/root/haskell-report/report/decls.verb,v 1.13 2001/11/01 13:43:43 simonpj Exp $
+% $Header: /home/cvs/root/haskell-report/report/decls.verb,v 1.14 2001/12/21 16:00:24 simonpj Exp $
 %
 %**<title>The Haskell 98 Report: Declarations</title>
 %*section 4
@@ -22,7 +22,7 @@ body   -> @{@ impdecls @;@ topdecls @}@
        | @{@ impdecls  @}@
        | @{@ topdecls  @}@
 
-topdecls -> topdecl_1 @;@ ... @;@ topdecl_n    & \qquad (n>=1)
+topdecls -> topdecl_1 @;@ ... @;@ topdecl_n    & (n>=1)
 topdecl        -> @type@ simpletype @=@ type
        |  @data@ [context @=>@] simpletype @=@ constrs [deriving]
         |  @newtype@ [context @=>@] simpletype @=@ newconstr [deriving]
@@ -31,24 +31,24 @@ topdecl     -> @type@ simpletype @=@ type
        |  @default@ @(@type_1 @,@ ... @,@ type_n@)@ & \qquad (n>=0)
        |  decl
 
-decls  -> @{@ decl_1 @;@ ... @;@ decl_n @}@            & \qquad (n>=0)
+decls  -> @{@ decl_1 @;@ ... @;@ decl_n @}@            & (n>=0)
 decl   -> gendecl
        |  (funlhs | pat^0) rhs
 
-cdecls -> @{@ cdecl_1 @;@ ... @;@ cdecl_n @}@          & \qquad (n>=0)
+cdecls -> @{@ cdecl_1 @;@ ... @;@ cdecl_n @}@          & (n>=0)
 cdecl  -> gendecl
        |  (funlhs | var) rhs
 
-idecls -> @{@ idecl_1 @;@ ... @;@ idecl_n @}@          & \qquad (n>=0)
-idecl  -> (funlhs | qfunlhs | var | qvar) 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                & \qquad (n>=1)
-vars   -> var_1 @,@ ... @,@ var_n              & \qquad (n>=1)
+ops    -> op_1 @,@ ... @,@ op_n                & (n>=1)
+vars   -> var_1 @,@ ... @,@ var_n              & (n>=1)
 fixity -> @infixl@ | @infixr@ | @infix@
 @@@
 \indexsyn{vars}%
@@ -576,7 +576,7 @@ 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 using the record syntax
+A constructor definition in a @data@ declaration using the record
 syntax (@C { ... }@) assigns labels to the components of the constructor.
 Constructors using field labels may be freely mixed with constructors
 without them. 
@@ -637,8 +637,6 @@ Section~\ref{strict-eval}) if "s_i" is of the form "@!@ t_i".  Pattern
 matching on "K" is not affected by strictness flags.
 }
 
-Lexically speaking, ``@!@'' is an ordinary "varsym" not a "reservedop"; it has special significance
-only in the context of the argument types of a @data@ declaration.
 
 \subsubsection{Type Synonym Declarations}
 \index{type synonym}
@@ -799,7 +797,7 @@ topdecl     -> @class@ [scontext @=>@] simpleclass [@where@ cdecls]
 scontext -> simpleclass
         |  @(@ simpleclass_1 @,@ ... @,@ simpleclass_n @)@             & (n>=0)
 simpleclass -> qtycls tyvar                    
-cdecls -> @{@ cdecl_1 @;@ ... @;@ cdecl_n @}@          & \qquad (n>=0)
+cdecls -> @{@ cdecl_1 @;@ ... @;@ cdecl_n @}@          & (n>=0)
 cdecl  -> gendecl
        |  (funlhs | var) rhs
 @@@
@@ -931,15 +929,10 @@ 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 @}@          & \qquad (n>=0)
-idecl  -> (funlhs | var | qfunlhs | qvar) rhs
-       |                                                       & (empty)
-qfunlhs        ->  qvar apat \{ apat \}
-       |   pat^{i+1} qvarop^{(a,i)} pat^{i+1}
-       |   lpat^i qvarop^{({\rm{}l},i)} pat^{i+1}
-       |   pat^{i+1} qvarop^{({\rm{}r},i)} rpat^i
-       |   @(@ qfunlhs @)@ apat \{ apat \}
+       |  @(@ 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}%
@@ -971,27 +964,45 @@ such as:
 @
 \eprog
 The declarations "d" may contain bindings only for the class
-methods\index{class method} of "C".  The declarations may not contain any type
+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 @return@ is in scope only
+with the qualified name @Monad.return@.
+\bprog
+@
+  module A where
+    import qualified Monad
+
+    instance Monad.Monad T where
+      return = ...
+      (>>=)  = ...
+@
+\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".
+
+% 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
@@ -1150,7 +1161,7 @@ including an empty deriving form: @deriving ()@.
 \index{overloading!defaults}
 
 @@@
-topdecl -> @default@ @(@type_1 @,@ ... @,@ type_n@)@ & \qquad (n>=0)
+topdecl -> @default@ @(@type_1 @,@ ... @,@ type_n@)@ & (n>=0)
 @@@
 \index{topdecl@@{\em topdecl} (@default@)}
 
@@ -1220,7 +1231,7 @@ default declaration}:
 "@default (@t_1 @,@ ... @,@ t_n@)@"
 \]
 where "n\geq0", and each
-"t_i" must be a monotype for which "@Num @t_i" holds.
+"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}
@@ -1260,7 +1271,7 @@ including the top level of a module.
 
 @@@
 gendecl -> vars @::@ [context @=>@] type
-vars   -> var_1 @,@ ...@,@ var_n               & \qquad (n>=1)
+vars   -> var_1 @,@ ...@,@ var_n               & (n>=1)
 @@@
 \indexsyn{signdecl}%
 \indexsyn{vars}%
@@ -1370,7 +1381,7 @@ to supply the more general type signature, @T a -> a@.
 @@@
 gendecl        -> fixity [integer] ops
 fixity -> @infixl@ | @infixr@ | @infix@
-ops    -> op_1 @,@ ... @,@ op_n                & \qquad (n>=1)
+ops    -> op_1 @,@ ... @,@ op_n                &  (n>=1)
 op     -> varop | conop 
 @@@
 \indexsyn{gendecl}%
@@ -1384,7 +1395,7 @@ 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 declaration group as
+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
@@ -1524,7 +1535,6 @@ gdrhs     ->  gd @=@ exp [gdrhs]
 gd     ->  @|@ exp^0 
 @@@
 \indexsyn{decl}%
-\indexsyn{qfunlhs}%
 \indexsyn{rhs}%
 \indexsyn{gdrhs}%
 \indexsyn{gd}%
index 28ced22..e12ef1a 100644 (file)
@@ -1,5 +1,5 @@
 %
-% $Header: /home/cvs/root/haskell-report/report/exps.verb,v 1.13 2001/11/02 16:26:48 simonpj Exp $
+% $Header: /home/cvs/root/haskell-report/report/exps.verb,v 1.14 2001/12/21 16:00:24 simonpj Exp $
 %
 %*section 3
 %**<title>The Haskell 98 Report: Expressions</title>
@@ -608,7 +608,7 @@ are class methods in the class @Enum@ as defined in the Prelude
 
 The semantics of arithmetic sequences therefore depends entirely
 on the instance declaration for the type "t".  
-Section~\ref{enum-class} for more details of which @Prelude@
+See Section~\ref{enum-class} for more details of which @Prelude@
 type are in @Enum@ and their semantics.
 
 
@@ -733,7 +733,7 @@ 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"@=@"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"   \\
@@ -829,12 +829,17 @@ Section~\ref{case-semantics}.
 %
 @@@
 exp -> @do@ @{@ stmts @}@             & (\tr{do expression})
-stmts -> stmt_1 ... stmt_n exp [@;@]  & \qquad (n>=0)
+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}%
@@ -900,10 +905,12 @@ 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.
 
@@ -1099,7 +1106,7 @@ pat^i     ->  pat^{i+1} [qconop^{({\rm{n}},i)} pat^{i+1}]
 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
+pat^{10} ->  apat
        |   gcon apat_1 ... apat_k              & (\tr{arity} gcon = k, k>=1)
 
 apat   ->  var [{\tt @@} apat]                 & (\tr{as pattern})
@@ -1380,7 +1387,7 @@ f ~(x,y,z) [a] | (a == y) = 1
 %           where (x,y,z) = t
 % @@
 % \eprog
-both @a@ and @y@ will be evaluated by @&&@ in the guard.
+both @a@ and @y@ will be evaluated by @==@ in the guard.
 
 
 \subsubsection{Formal Semantics of Pattern Matching}
index d44b0f2..8309518 100644 (file)
@@ -21,7 +21,7 @@ L.~Damas and R.~Milner.
   Programming Languages}, pages 207--212, Albuquerque, N.M., January 1982.
 
 \bibitem{hindley69}
-JR.~Hindley.
+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.
@@ -44,9 +44,9 @@ P.~Penfield, Jr.
   Francisco, September 1981.
 
 \bibitem{libraries}
-Simon Peyton Jones and John Hughes (editors).
+Simon Peyton Jones (editor).
 \newblock {S}tandard {L}ibraries for the {H}askell 98 {P}rogramming {L}anguage, 
-\newblock 1 February 1999.
+\newblock 2001.
 
 \bibitem{peyton-jones:book}
 S.L. Peyton~Jones.
index 99617f7..aed5cae 100644 (file)
@@ -1,5 +1,5 @@
 %
-% $Header: /home/cvs/root/haskell-report/report/haskell.verb,v 1.11 2001/10/02 09:09:26 simonpj Exp $
+% $Header: /home/cvs/root/haskell-report/report/haskell.verb,v 1.12 2001/12/21 16:00:24 simonpj Exp $
 %
 
 % NOTE:--------------------------------------------------------------
 {\LARGE\bf Programming Language} \\[.3in]
 {\huge\bf Haskell 98} \\[.3in]
 {\Large\bf A Non-strict, Purely Functional Language} \\[.3in]
-{\large\bf Revised: October 2001}
+{\large\bf Revised: December 2001}
 \end{center}
 \vspace{.15in}
 \begin{center} \large
@@ -454,21 +454,22 @@ Authors' affiliations:
 (6)~Los Alamos National Laboratory
 (7)~Intermetrics
 (8)~Microsoft Research, Cambridge
-(9)~University of Nottingham
-(10)~Utrecht University
-(11)~Bell Labs
+(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 and John Hughes
+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 entirity,
+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
index 2b649cd..8974bf7 100644 (file)
@@ -26,7 +26,7 @@ style=article
 ~nxt=<a href="~next.html">next</a>
 ~funct=<a href="prelude-index.html">function index</a>
 ~contents=<a href="index98.html">contents</a>
-~foot=<br><font size=2>October 2001</font>
+~foot=<br><font size=2>December 2001</font>
 ~footer=<hr>~id~top | ~back | ~nxt | ~contents | ~funct ~foot
 ~sfooter=<hr>~id~top | back | ~nxt | ~contents | ~funct ~foot
 ~efooter=<hr>~id~top | ~back | next | ~contents | ~funct ~foot
index 1da7859..7688666 100644 (file)
@@ -96,6 +96,7 @@
 \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 7308a48..7046835 100644 (file)
@@ -5,7 +5,7 @@
 <img src="h98.gif" alt="Haskell 98">
 
 <h3>Haskell 98: A Non-strict, Purely Functional Language</h3>
-<h3 align="center">Revised: October 2001</h3>
+<h3 align="center">Revised: December 2001</h3>
 </div>
 <hr>
 <h3>Brief Table of Contents</h3>
index dcdc3ab..7b40c97 100644 (file)
@@ -59,10 +59,10 @@ 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 ()
+  putChar  :: Char -> IO ()
+  putStr   :: String -> IO ()
+  putStrLn :: String -> IO ()  -- adds a newline
+  print    :: Show a => a -> IO ()
 @
 \eprog
 \indextt{putChar}
@@ -89,12 +89,12 @@ 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
+  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}%
@@ -144,11 +144,11 @@ 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
+  type FilePath =  String
+  
+  writeFile  :: FilePath -> String -> IO ()
+  appendFile :: FilePath -> String -> IO ()
+  readFile   :: FilePath           -> IO String
 @
 \eprog
 \indextt{writeFile}%
@@ -177,8 +177,8 @@ 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
+  (>>=) :: IO a -> (a -> IO b) -> IO b 
+  (>>)  :: IO a -> IO b        -> IO b
 @
 \eprog
 For example,
@@ -245,8 +245,8 @@ describing the error.
 Exceptions are raised and caught using the following functions:
 \bprog
 @
-  ioError         ::  IOError -> IO a
-  catch           ::  IO a    -> (IOError -> IO a) -> IO a 
+  ioError :: IOError -> IO a
+  catch   :: IO a    -> (IOError -> IO a) -> IO a 
 @
 \eprog
 \indextt{ioError}%
index 6efe57a..05ce5ed 100644 (file)
@@ -1,5 +1,5 @@
 %
-% $Header: /home/cvs/root/haskell-report/report/lexemes.verb,v 1.9 2001/11/01 13:43:43 simonpj Exp $
+% $Header: /home/cvs/root/haskell-report/report/lexemes.verb,v 1.10 2001/12/21 16:00:25 simonpj Exp $
 %
 %*section 2
 %**<title>Haskell 98 Lexical Structure</title>
@@ -113,13 +113,13 @@ 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 commment.
+does start a comment.
 
 A nested comment\index{comment!nested} begins with ``@{-@'' 
 and ends with ``@-}@''.  No legal lexeme starts with ``@{-@''; 
-hence, for exmaple, ``@{---@'' starts a nested comment despite the trailing dashes.
+hence, for example, ``@{---@'' starts a nested comment despite the trailing dashes.
 
-The comment itself is not lexically analysed.  Instead the first
+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
@@ -315,6 +315,14 @@ gap     ->  @\@ whitechar \{whitechar\} @\@
 \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"@.
index 3449e05..71207fe 100644 (file)
@@ -1,5 +1,5 @@
 %
-% $Header: /home/cvs/root/haskell-report/report/literate.verb,v 1.3 2001/09/24 15:06:01 simonpj Exp $
+% $Header: /home/cvs/root/haskell-report/report/literate.verb,v 1.4 2001/12/21 16:00:25 simonpj Exp $
 %
 %**<title>The Haskell 98 Report: Literate Comments</title>
 %*section C
@@ -56,7 +56,13 @@ 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.  It is not necessary
+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
index de6487d..fd07b40 100644 (file)
@@ -1,5 +1,5 @@
 %
-% $Header: /home/cvs/root/haskell-report/report/modules.verb,v 1.15 2001/11/01 13:43:43 simonpj Exp $
+% $Header: /home/cvs/root/haskell-report/report/modules.verb,v 1.16 2001/12/21 16:00:25 simonpj Exp $
 %
 %**<title>The Haskell 98 Report: Modules</title>
 %*section 5
@@ -9,9 +9,9 @@
 \index{module}
 
 A module defines a collection of values, datatypes, type synonyms,
-classes, etc.~(see Section~\ref{declarations}) in an environment created
-by a set of {\em imports}, resources brought into scope from other modules, 
-and {\em exports} some of these resources, making them available to
+classes, etc.~(see Section~\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
@@ -92,8 +92,8 @@ body   -> @{@ impdecls @;@ topdecls @}@
        | @{@ topdecls @}@
 
 modid       -> conid
-impdecls     -> impdecl_1 @;@ ... @;@ impdecl_n        & \qquad (n>=1)
-topdecls     -> topdecl_1 @;@ ... @;@ topdecl_n        & \qquad (n>=1)
+impdecls     -> impdecl_1 @;@ ... @;@ impdecl_n        & (n>=1)
+topdecls     -> topdecl_1 @;@ ... @;@ topdecl_n        & (n>=1)
 @@@
 
 \indexsyn{module}%
@@ -123,18 +123,17 @@ for the top level of the module.
 \index{export list}
 
 @@@
-exports         -> @(@ export_1 @,@ ... @,@ export_n [ @,@ ] @)@ & \qquad (n>=0)
+exports         -> @(@ export_1 @,@ ... @,@ export_n [ @,@ ] @)@ & (n>=0)
 
 export   -> qvar
-        |  qtycon [@(..)@ | @(@ qcname_1 @,@ ... @,@ qcname_n @)@] & \qquad (n>=0)
-        |  qtycls [@(..)@ | @(@ qvar_1 @,@ ... @,@ qvar_n @)@] & \qquad (n>=0)
+        |  qtycon [@(..)@ | @(@ cname_1 @,@ ... @,@ cname_n @)@] &  (n>=0)
+        |  qtycls [@(..)@ | @(@ var_1 @,@ ... @,@ var_n @)@] &  (n>=0)
          |  @module@ modid
 
-qcname   -> qvar | qcon
+cname   -> var | con
 @@@
 \indexsyn{exports}%
 \indexsyn{export}%
-\indexsyn{qcname}%
 
 An {\em export list} identifies the entities to be exported by a
 module declaration.  A module implementation may only export an entity
@@ -147,7 +146,7 @@ Entities in an export list may be named as follows:
 \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".
+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.  
 
@@ -162,20 +161,33 @@ 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@(@qcname_1@,@\ldots@,@qcname_n@)@$, where the $qcname_i$
-name only constructors and field names in $T$, 
+The form $T@(@c_1@,@\ldots@,@c_n@)@$, 
 names the type and some or all of its constructors and field names.  
-The $qcname_i$ must not contain duplications.  
+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}
-Data constructors cannot be named in export lists in any other way.
+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".
+@type@ declaration may be named by the form "T", where "T" is in scope.
 \index{type synonym}
 
 \item
@@ -186,13 +198,17 @@ declared in a @class@ declaration may be named in one of three ways:
 \item
 The form "C" names the class {\em but not the class methods}.
 \item
-The form $C@(@f_1@,@\ldots@,@f_n@)@$, where
-the $f_i$ must be class methods of $C$, names the class and some or all
-of its methods.  The $f_i$ must not contain duplications.
+The form $C@(@f_1@,@\ldots@,@f_n@)@$, names the class and some or all
+of its methods.  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@'' abbreviates the set of all entities whose
@@ -260,20 +276,20 @@ even though there are no name clashes within module @A@ itself.
 @@@
 impdecl   -> @import@ [@qualified@] modid [@as@ modid] [impspec]
          |     & (empty declaration)
-impspec   -> @(@ import_1 @,@ ... @,@ import_n [ @,@ ] @)@ & \qquad (n>=0)
-             |  @hiding@ @(@ import_1 @,@ ... @,@ import_n [ @,@ ] @)@ & \qquad (n>=0)
+impspec   -> @(@ import_1 @,@ ... @,@ import_n [ @,@ ] @)@ & (n>=0)
+             |  @hiding@ @(@ import_1 @,@ ... @,@ import_n [ @,@ ] @)@ & (n>=0)
 
 import    -> var
-         |  tycon [ @(..)@ | @(@ cname_1 @,@ ... @,@ cname_n @)@] & \qquad (n>=1)
-         |  tycls [@(..)@ | @(@ var_1 @,@ ... @,@ var_n @)@] & \qquad (n>=0)
+         |  tycon [ @(..)@ | @(@ cname_1 @,@ ... @,@ cname_n @)@] &  (n>=1)
+         |  tycls [@(..)@ | @(@ var_1 @,@ ... @,@ var_n @)@] & (n>=0)
 cname     -> var | con
 @@@
 %             var
 %          |  tycon
 %          |  tycon @(..)@
-%          |  tycon @(@ con_1 @,@ ... @,@ con_n@)@ & \qquad (n>=1)
+%          |  tycon @(@ con_1 @,@ ... @,@ con_n@)@ & (n>=1)
 %          |  tycls @(..)@
-%          |  tycls @(@ var_1 @,@ ... @,@ var_n@)@ & \qquad (n>=0)
+%          |  tycls @(@ var_1 @,@ ... @,@ var_n@)@ & (n>=0)
 \indexsyn{impdecl}%
 \indexsyn{impspec}%
 \indexsyn{import}%
@@ -296,7 +312,7 @@ 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 speaking, the terminal symbols ``@as@'', ``@qualified@'' and
+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.
@@ -473,7 +489,6 @@ declarations can have an empty export list.  For example
 \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.}
index b7d627d..592b463 100644 (file)
@@ -1,5 +1,5 @@
 %
-% $Header: /home/cvs/root/haskell-report/report/standard-prelude.verb,v 1.1 2001/03/28 14:13:42 simonpj Exp $
+% $Header: /home/cvs/root/haskell-report/report/standard-prelude.verb,v 1.2 2001/12/21 16:00:25 simonpj Exp $
 %
 %**<title>The Haskell 98 Report: Standard Prelude</title>
 %*section A
 In this appendix 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 {\em not} required that the specification be implemented as shown here.
+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 {\em not} required to use 
+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.
@@ -34,12 +41,20 @@ 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
+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.
+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@.
 
-\medskip
+\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
index 92d1e5a..9b1aa54 100644 (file)
@@ -1,5 +1,5 @@
 %
-% $Header: /home/cvs/root/haskell-report/report/syntax-iso.verb,v 1.7 2001/11/01 13:43:43 simonpj Exp $
+% $Header: /home/cvs/root/haskell-report/report/syntax-iso.verb,v 1.8 2001/12/21 16:00:25 simonpj Exp $
 %
 %**<title>Haskell 98 Syntax</title>
 %*section B
@@ -153,17 +153,19 @@ takes the form of a function "L" that performs the translation.
 The input to "L" is:
 \begin{itemize}
 \item 
-A stream of tokens as specified by the lexical syntax in the Haskell report,
+A stream of lexemes as specified by the lexical syntax in the Haskell report,
 with the following additional tokens: 
 \begin{itemize}
-\item If the first token after a @let@, @where@, @do@, or @of@ keyword is not @{@, 
-it is preceded by "\{n\}" where "n" is the indentation of the token. 
-\item If the first token of a module is not @{@ or @module@, 
-then it is preceded by "\{n\}" where "n" is the indentation of the token. 
-\item Where the start of a token does not follow any complete token on the
-   same line, this token is preceded by "<n>" where "n"
-   is the indentation of the token, provided that it is not,
+\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 does not follow a complete lexeme on the
+   same line, this lexeme is preceded by "<n>" where "n"
+   is the indentation of the lexeme, provided that it is not,
    as a consequence of the first two rules, preceded by "\{n\}".
+   (A string literal may span multiple lines -- Section~\ref{lexemes-char}.)
 \end{itemize}
 
 \item A stack of ``layout contexts'', in which each element is either:
@@ -192,48 +194,61 @@ are considered to be of the same, fixed, width as an ASCII character.
 
 The application
 \[
-L~tokens~[0]
+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~ (<n>:ts)~ (m:ms)   & = & @;@ ~:~ (L~ ts~(m:ms))           &\mbox{if}~ m = n \\
+%                            & = & @}@ ~:~ (L~ (<n>: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~(<n>: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~ (t:ts)~ (m:ms)       & = & @}@ ~:~ (L~ (t:ts)~ ms)           & \mbox{if}~ m /= 0 ~\mbox{and}~ \mbox{parse-error}(t) \\
-                           &&& (Note~ 1) \\
-  \\
      L~ (<n>:ts)~ (m:ms)   & = & @;@ ~:~ (L~ ts~(m:ms))           &\mbox{if}~ m = n \\
                            & = & @}@ ~:~ (L~ (<n>:ts)~ ms)       & \mbox{if}~ n < m \\
-                           & = & L~ ts~(m:ms)                   & otherwise \\
-     \\
-     L~ (@}@:ts)~ (0:ms)     & = & @}@ ~:~ (L~ ts~ms)     &                       (Note~ 2) \\
-     \\
-     L~ (\{n\}:ts)~ (m:ms)   & = & @{@ ~:~ (L~ ts~(n:m:ms))         & \mbox{if}~n > m,~   (Note~ 3)\\
+     L~ (<n>:ts)~ms        & = & L~ ts~ms \\
 \\
-     L~ (@{@:ts)~ ms         & = & @{@ ~:~ (L~ ts~(0:ms))                   &     (Note~ 4)\\
-     \\
+     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~ (<n>: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~ [0]            & = & \emptystr\\
-     L~ \emptystr~ (m:ms)         & = & @}@ ~:~ L~ \emptystr~ ms          & \mbox{if}~m \neq 0~  (Note~ 5)
+     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.] 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 2.] By matching against 0 for the current layout context, 
-we ensure that an explicit close brace can only match an explicit open brace. 
-
-\item[Note 3.] A nested context must be further indented 
+\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
@@ -248,12 +263,29 @@ layout error.  An example is:
 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 $<n>$, 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.
+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 5.] At the end of the input, any pending close-braces are inserted. 
+\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}
 
@@ -288,7 +320,7 @@ body   -> @{@ impdecls @;@ topdecls @}@
        | @{@ impdecls  @}@
        | @{@ topdecls  @}@
 
-impdecls     -> impdecl_1 @;@ ... @;@ impdecl_n        & \qquad (n>=1)
+impdecls     -> impdecl_1 @;@ ... @;@ impdecl_n        &  (n>=1)
 @@@
 \indexsyn{module}%
 \indexsyn{body}%
@@ -296,28 +328,26 @@ impdecls     -> impdecl_1 @;@ ... @;@ impdecl_n   & \qquad (n>=1)
 \indexsyn{impdecls}%
 
 @@@
-exports         -> @(@ export_1 @,@ ... @,@ export_n [ @,@ ] @)@ & \qquad (n>=0)
+exports         -> @(@ export_1 @,@ ... @,@ export_n [ @,@ ] @)@ & (n>=0)
 
 export   -> qvar
-        |  qtycon [@(..)@ | @(@ qcname_1 @,@ ... @,@ qcname_n @)@] & \qquad (n>=0)
-        |  qtycls [@(..)@ | @(@ qvar_1 @,@ ... @,@ qvar_n @)@] & \qquad (n>=0)
+        |  qtycon [@(..)@ | @(@ cname_1 @,@ ... @,@ cname_n @)@] & (n>=0)
+        |  qtycls [@(..)@ | @(@ qvar_1 @,@ ... @,@ qvar_n @)@] & (n>=0)
          |  @module@ modid
-qcname   -> qvar | qcon
 @@@
 \indexsyn{exports}%
 \indexsyn{export}%
-\indexsyn{qcname}%
 
 @@@
 impdecl   -> @import@ [@qualified@] modid [@as@ modid] [impspec]
          |     & (\tr{empty declaration})
 
-impspec   -> @(@ import_1 @,@ ... @,@ import_n [ @,@ ] @)@ & \qquad (n>=0)
-             |  @hiding@ @(@ import_1 @,@ ... @,@ import_n [ @,@ ] @)@ & \qquad (n>=0)
+impspec   -> @(@ import_1 @,@ ... @,@ import_n [ @,@ ] @)@ & (n>=0)
+             |  @hiding@ @(@ import_1 @,@ ... @,@ import_n [ @,@ ] @)@ &  (n>=0)
 
 import    -> var
-         |  tycon [ @(..)@ | @(@ cname_1 @,@ ... @,@ cname_n @)@] & \qquad (n>=1)
-         |  tycls [@(..)@ | @(@ var_1 @,@ ... @,@ var_n @)@] & \qquad (n>=0)
+         |  tycon [ @(..)@ | @(@ cname_1 @,@ ... @,@ cname_n @)@] & (n>=1)
+         |  tycls [@(..)@ | @(@ var_1 @,@ ... @,@ var_n @)@] & (n>=0)
 cname     -> var | con
 @@@
 \indexsyn{impdecl}%
@@ -326,37 +356,37 @@ cname     -> var | con
 \indexsyn{cname}%
 
 @@@
-topdecls -> topdecl_1 @;@ ... @;@ topdecl_n    & \qquad (n>=0)
+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@)@ & \qquad (n>=0)
+       |  @default@ @(@type_1 @,@ ... @,@ type_n@)@ & (n>=0)
        |  decl
 @@@
 \indexsyn{topdecls}%
 \indexsyn{topdecl}%
 
 @@@
-decls  -> @{@ decl_1 @;@ ... @;@ decl_n  @}@           & \qquad (n>=0)
+decls  -> @{@ decl_1 @;@ ... @;@ decl_n  @}@           &  (n>=0)
 decl   -> gendecl
        |  (funlhs | pat^0) rhs
 
-cdecls -> @{@ cdecl_1 @;@ ... @;@ cdecl_n  @}@         & \qquad (n>=0)
+cdecls -> @{@ cdecl_1 @;@ ... @;@ cdecl_n  @}@         &  (n>=0)
 cdecl  -> gendecl
        |  (funlhs | var) rhs
 
-idecls -> @{@ idecl_1 @;@ ... @;@ idecl_n  @}@         & \qquad (n>=0)
-idecl  -> (funlhs | qfunlhs | var | qvar) 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                & \qquad (n>=1)
-vars   -> var_1 @,@ ...@,@ var_n               & \qquad (n>=1)
+ops    -> op_1 @,@ ... @,@ op_n                & (n>=1)
+vars   -> var_1 @,@ ...@,@ var_n               & (n>=1)
 fixity -> @infixl@ | @infixr@ | @infix@
 @@@
 \indexsyn{vars}%
@@ -389,11 +419,11 @@ gtycon    -> qtycon
           |  @(,@\{@,@\}@)@                    & (\tr{tupling constructors})
 
 context -> class
-        |  @(@ class_1 @,@ ... @,@ class_n @)@         & (n>=0)
+        |  @(@ class_1 @,@ ... @,@ class_n @)@         &  (n>=0)
 class  -> qtycls tyvar                 
-       |  qtycls @(@ tyvar atype_1 ...  atype_n @)@ & (n>=1)
+       |  qtycls @(@ tyvar atype_1 ...  atype_n @)@ &  (n>=1)
 scontext -> simpleclass
-        |  @(@ simpleclass_1 @,@ ... @,@ simpleclass_n @)@             & (n>=0)
+        |  @(@ simpleclass_1 @,@ ... @,@ simpleclass_n @)@             &  (n>=0)
 simpleclass -> qtycls tyvar                    
 @@@
 \indexsyn{type}%
@@ -407,15 +437,15 @@ simpleclass -> qtycls tyvar
 
 
 @@@
-simpletype -> tycon tyvar_1 ... tyvar_k & (k>=0)
-constrs           -> constr_1 @|@ ... @|@ constr_n     & (n>=1)
+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)
+           |  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)
+deriving   -> @deriving@ (dclass | @(@dclass_1@,@ ... @,@ dclass_n@)@)&  (n>=0)
 dclass     -> qtycls
 @@@
 \indexsyn{simpletype}%
@@ -442,12 +472,6 @@ funlhs     ->  var apat \{ apat \}
        |   pat^{i+1} varop^{({\rm{}r},i)} rpat^i
        |   @(@ funlhs @)@  apat \{ apat \}
 
-qfunlhs        ->  qvar apat \{ apat \}
-       |   pat^{i+1} qvarop^{(a,i)} pat^{i+1}
-       |   lpat^i qvarop^{({\rm{}l},i)} pat^{i+1}
-       |   pat^{i+1} qvarop^{({\rm{}r},i)} rpat^i
-       |   @(@ qfunlhs @)@ apat \{ apat \}
-
 rhs    ->  @=@ exp [@where@ decls]
        |   gdrhs [@where@ decls]
 
@@ -456,7 +480,6 @@ gdrhs       ->  gd @=@ exp [gdrhs]
 gd     ->  @|@ exp^0 
 @@@
 \indexsyn{funlhs}%
-\indexsyn{qfunlhs}%
 \indexsyn{rhs}%
 \indexsyn{gdrhs}%
 \indexsyn{gd}%
@@ -505,14 +528,14 @@ qual      -> pat @<-@ exp         & (\tr{generator})
          | @let@ decls         & (\tr{local declaration})
          | exp                         & (\tr{guard})
 
-alts   ->  alt_1 @;@ ... @;@ alt_n             & (n>=0)
+alts   ->  alt_1 @;@ ... @;@ alt_n             &  (n>=0)
 alt    ->  pat @->@ exp [@where@ decls]
        |   pat gdpat [@where@ decls]
        |                                       & (empty alternative)
 
 gdpat   ->  gd @->@ exp [ gdpat ]
 
-stmts -> stmt_1 ... stmt_n exp [@;@]  & \qquad (n>=0)
+stmts -> stmt_1 ... stmt_n exp [@;@]  &  (n>=0)
 stmt -> exp @;@
       | pat @<-@ exp @;@
       | @let@ decls @;@
@@ -538,7 +561,7 @@ pat^i       ->  pat^{i+1} [qconop^{({\rm{}n},i)} pat^{i+1}]
 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
+pat^{10} ->  apat
        |   gcon apat_1 ... apat_k              & (\tr{arity} gcon = k, k>=1)
 @@@
 \indexsyn{pat}%
index 26383b8..75d81cb 100644 (file)
@@ -1,11 +1,12 @@
 %
-% $Header: /home/cvs/root/haskell-report/report/syntax-lexical.verb,v 1.6 2001/11/02 16:26:48 simonpj Exp $
+% $Header: /home/cvs/root/haskell-report/report/syntax-lexical.verb,v 1.7 2001/12/21 16:00:25 simonpj Exp $
 % 
 
-@@@ 
+@@@
 
 program                -> \{ lexeme | whitespace \}
-lexeme          -> qvarid | qconid | qop | literal | special | reservedop | reservedid
+lexeme          -> qvarid | qconid | qvarsym | qconsym 
+                | literal | special | reservedop | reservedid
 literal                -> integer | float | char | string
 special                -> @(@ | @)@ | @,@ | @;@ | @[@ | @]@ | \bkq | @{@ | @}@
 
@@ -21,7 +22,8 @@ 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\} newline
+
+comment         -> dashes [ any_{\langle symbol\rangle}  \{any\} ] newline
 dashes         -> @--@ \{@-@\}
 opencom                -> @{-@
 closecom       -> @-}@
@@ -49,7 +51,7 @@ uniDigit        -> \tr{any Unicode decimal digit}
 octit   -> @0@ | @1@ | ... | @7@
 hexit   -> digit | @A@ | ... | @F@ | @a@ | ... | @f@
 
-@@@ 
+@@@
 
 \indexsyn{program}%
 \indexsyn{lexeme}%