Towards the revised Reports
[haskell-report.git] / haskell98-bugs.html
1 <html>
2 <head>
3 </head>
4 <HEAD>
5 <TITLE>Haskell 98: ERRATA</title></head>
6 </head>
7 </head>
8 </head>
9 </head>
10 </HEAD>
11 <BODY>
12 <div align=center>
13 <img src="h98.gif" alt="Haskell 98">
14 </div>
15
16 <h1>Errata in the
17 <a href="http://haskell.cs.yale.edu/definition/">Haskell 98 Language Report</a></h1>
18
19 <ul>
20 <p><li> <strong>Title page</strong>. Add the paragraph:
21 <p>
22 "Copyright (c) Simon Peyton Jones and John Hughes.
23 <p>
24 The authors intend this Report to belong to the entire Haskell
25 community, and so we grant permission to copy and
26 distribute it for any purpose, provided that it is
27 reproduced in its entireity, including this Notice. Modified
28 versions of this Report may also be copied and distributed for any purpose,
29 provided that the modified version is clearly presented as such,
30 and that it does not claim to be a definition of the language Haskell 98."
31
32 <p><li> <strong>Page 9, Section 2.6, Character and String Literals.</strong>
33 In the production for "cntrl" replace "ASClarge" by "ascLarge".
34
35 <p><li> <strong>Page 10, Section 2.7, Layout.</strong>
36 In the middle of the third paragraph, just before the sentence beginning
37 "A close brace is also inserted...", add the following sentence:
38 <p>
39 "If the indentation of the non-brace lexeme immediately
40 following a <tt>where</tt>, <tt>let</tt>,
41 <tt>do</tt> or <tt>of</tt> is less than or equal to the <em>current</em> indentation level,
42 then instead of starting a layout, an empty list "<tt>{}</tt>" is inserted, and
43 layout processing occurs for the current level (i.e. insert a semicolon or close brace)."
44
45 <p><li> <strong>Page 11, Figures 1 and 2</strong>. In both figures the signature for <tt>size</tt>
46 should be
47 <pre>
48 size :: Stack a -> Int
49 </pre>
50
51 <p><li> [Apr 20001] <strong>Page 14, Section 3.1, Errors.</strong> In the first sentence of
52 the section, after "indistinguishable" add "by a Haskell program".
53
54 <p><li> [Apr 20001] <strong>Page 20, Section 3.10, Arithmetic sequences.</strong>
55 In the second paragraph, in the sentence "For the type <tt>Integer</tt>,
56 arithmetic sequences have the following meaning...", replace "<tt>Integer</tt>"
57 with "<tt>Int</tt>".
58
59 <p><li> [Apr 20001] <strong>Page 21, Section 3.11, List Comprehensions; and Page 128.</strong>
60 <ul> <li> In the production for "aexp", change the "n >= 0" to "n >= 1".
61 <li> Remove the production for (empty qualifier)
62 </ul>
63 This change ensures that there is at least one qualifier in list comprehension,
64 and no qualifier is empty. The translation lower down page 23 is then
65 not utterly rigorous, because Q can be empty, and when it is there is no preceding
66 comma, but I reckon it would make matters worse to "fix" it.
67
68 <p><li> [Apr 20001] <strong>Page 23, Section 3.14, Do Expressions;
69 and Page 128, Appendix B.4, Context Free Syntax.</strong>
70 <ul>
71 <li>
72 Change the production for <em>stmts</em> to read:
73 <pre>
74 stmts -> stmt1 ... stmtn exp [;] (n>=0)
75 </pre>
76 <li> Add "<tt>;</tt>" to the end of each of the four productions for <em>stmt</em>.
77 </ul>
78 That is, every list of statements must end in an expression, optionally
79 followed by a semicolon.
80
81 <p><li> [Apr 20001] <strong>Page 31,33, Figures 3 and 4, Semantics of Case Expressions.</strong>
82 Replace "completely new variable" by "new variable" in these two figures. (Some clauses
83 said "new" and some "completely new" which is misleadingly inconsistent.)
84
85 <p><li> [Apr 20001] <strong>Page 33, Figure 4, Semantics of Case Expressions Part 2.</strong>
86 In clause (r) replace "e0" by "v" throughout.
87
88 <p><li> <strong>Page 40, Section 4.2.1, Algebraic Datatype Declarations.</strong>
89 In the bottom paragraph on the page, before "The context in the data declaration
90 has no other effect whatsoever" add the following:
91 <p>
92 "Pattern matching against <tt>ConsSet</tt> also gives rise to an <tt>Eq a</tt>
93 constraint. For example:
94 <pre>
95 f (ConsSet a s) = a
96 </pre>
97 the function <tt>f</tt> has inferred type <tt>Eq a => Set a -> a</tt>."
98
99 <p><li> <strong>Page 41, Section 4.2.1, subsection Labelled Fields.</strong>
100 At the end of the subsection, add a new paragraph:
101 <p>
102 "The pattern "<tt>F {}</tt>" matches any value built with constructor <tt>F</tt>,
103 <em>whether or not <tt>F</tt> was declared with record syntax</em>."
104
105 <p><li> [Apr 2001] <strong>Page 42, Section 4.2.1, subsection Labelled Fields.</strong>
106 Change "occurance" to "occurrence" in the translation box at the very end of
107 the section.
108
109 <p><li> <strong>Page 49, Section 4.3.4, Ambiguous Types...</strong>
110 In the third paragraph from the end of Section 4.3.4, replace "...an ambiguous
111 type variable is defaultable if at least one of its classes is a numeric class..."
112 by "...an ambiguous type variable, v, is defaultable if v appears only in constraints
113 of the form (C v), where C is a class, and if at least one of its classes is
114 a numeric class...".
115 <p>
116 The new phrase is "if v appears only in constraints of the
117 form (C v) where C is a class". Without this condition the rest of the
118 sentence does not make sense.
119
120 <p><li> [Apr 20001] <strong>Page 53, Section 4.3.3.</strong> Replace "For example, these two function
121 definitions are equivalent:", and the two lines of code that follow by:
122 <br>
123 "For example, these three function definitions are all equivalent:
124 <pre>
125 plus x y z = x+y+z
126 x `plus` y = \ z -> x+y+z
127 (x `plus` y) z = x+y+z
128 </pre>"
129 (This change makes explicit that an infix operator with more than two arguments
130 can have all of them on the LHS.)
131
132 <p><li> [Apr 20001] <strong>Page 54, Section 4.4.3, subsection Function Bindings.</strong>
133 In the first translation scheme ("The general binding form for functions..."),
134 the <em>xn</em> should be <em>xk</em> (suitably subscripted in both cases!),
135 and all three <em>m</em> subscripts should be <em>n</em>.
136
137 <p><li> <strong>Page 57, Section 4.5.3, Context reduction errors.</strong>
138 The example
139 <pre>
140 f :: (Monad m, Eq (m a)) => a -> m a -> Bool
141 f x y = x == return y
142 </pre>
143 is wrong; it should read
144 <pre>
145 f x y = return x == y
146 </pre>
147
148 <p><li> <strong>Page 66, Section 5.3, Import Declarations, numbered item 2.</strong>
149 Start a new paragraph before the sentence "The hiding clause only applies to unqualified
150 names...".
151
152 <p><li><strong>Page 67, Section 5.3.2, Local aliases</strong>.
153 The the last example in the section should read:
154 <pre>
155 import Foo as A(f)
156 </pre>
157
158 <p><li> <strong>Page 69, Section 5.5.2, Name clashes.</strong>
159 At the very end of the section, add the following clarification:
160 <p>
161 "The name occurring in a type signature or fixity declarations is always
162 unqualified, and unambiguously refers to another declaration in the
163 same declaration list (except that the fixity declaration for a class method
164 can occur at top level --- Section 4.4.2). For example, the following
165 module is legal:
166 <pre>
167 module F where
168 sin :: Float -> Float
169 sin x = (x::Float)
170
171 f x = Prelude.sin (F.sin x)
172 </pre>
173 The local declaration for <tt>sin</tt> is legal, even though
174 the <tt>Prelude</tt> function <tt>sin</tt> is implicitly in scope.
175 The references to
176 <tt>Prelude.sin</tt> and <tt>F.sin</tt> must both be qualified to make
177 it unambigous which <tt>sin</tt> is meant.
178 However, the unqualified name "<tt>sin</tt>" in the type
179 signature in the first line of <tt>F</tt> unambiguously refers to the
180 local declaration for <tt>sin</tt>."
181
182 <p><li> <strong>Page 71, Section 5.6.2, Shadowing Prelude Names.</strong>
183 Replace the example at the beginning of the section, and the entire
184 following paragraph, with the following
185 "<pre>
186 module A( null, nonNull ) where
187 import Prelude hiding( null )
188 null, nonNull :: Int -> Bool
189 null x = x == 0
190 nonNull x = not (null x)
191 </pre>
192 Module <tt>A</tt> redefines <tt>null</tt>, and contains an unqualified reference
193 to <tt>null</tt> on the right hand side of <tt>nonNull</tt>.
194 The latter would be ambiguous without the "<tt>hiding(null)</tt>" on the
195 "<tt>import Prelude</tt>" statement.
196 Every module that imports <tt>A</tt> unqualified, and then makes an unqualified
197 reference to <tt>null</tt> must also resolve the ambiguous use of <tt>null</tt>
198 just as <tt>A</tt> does. Thus there is little danger of accidentally shadowing
199 Prelude names."
200
201 <p><li> [Apr 2001] <strong>Page 74, Section 6.1.6, Function Types.</strong>
202 Delete the sentence "Functions are an instance of the <tt>Show</tt> class but not <tt>Read</tt>".
203
204 <p><li> [Apr 2001] <strong>Page 76, Section 6.3, Standard Haskell classes.</strong>
205 There is a formatting error in the example. There should be a new line
206 after "the declaration of Class Eq is:", and before the sentence beginning
207 "This declaration gives default method declarations...".
208
209 <p><li> [Apr 2001] <strong>Page 78, Section 6.3.3, The Read and Show Classes.</strong>
210 After "The <tt>Read</tt> and <tt>Show</tt> classes are used to convert values
211 to and from strings." add the sentence:
212 "The <tt>Int</tt> argument to <tt>showsPrec</tt> and <tt>readsPrec</tt> gives the operator
213 precedence of the enclosing context (see Appendix D.4)."
214 (Clarification only.)
215
216 <p><li><strong>Page 80, Section 6.3.6, Class Monad.</strong>
217 Right at the bottom of the page, replace "However, for IO, the fail
218 method invokes error." by "For IO, the fail method raises a user
219 exception in the IO monad (see Section 7.3)."
220
221 <p><li> [Apr 2001] <strong>Page 84, Section 6.4, Fig 7; and bottom of page 86, Section 6.4.6.</strong>
222 <pre>
223 fromRealFrac :: (RealFrac a, Fractional b) => a -> b
224 </pre>
225 should be replaced by
226 <pre>
227 realToFrac :: (Real a, Fractional b) => a -> b
228 </pre>
229
230 <p><li><strong>Page 90, Section 7.3, Exception handling in the IO monad.</strong>
231 After the first paragraph give the following type signature:
232 <pre>
233 userError :: String -> IOError
234 </pre>
235 Also add an index entry for <tt>userError</tt> on this page.
236 (These changes are purely presentational.)
237
238 <p><li> [Apr 2001] <strong>Page 90, Section 7.3, Exception handling in the IO monad.</strong>
239 After the above signature for <tt>userError</tt>, add the following:
240 "The <tt>fail</tt> method of the <tt>IO</tt> instance of the <tt>Monad</tt> class (Section 6.3.6) raises a
241 <tt>userError</tt>, thus:
242 <pre>
243 instance Monad IO where
244 ...bindings for return, (>>=), (>>)
245
246 fail s = ioError (userError s)
247 </pre>"
248
249 <p><li><strong>Page 94, Appendix A, Standard Prelude, class <tt>Enum</tt>.</strong>
250 After the default method for <tt>enumFromTo</tt> add
251 <pre>
252 enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..]
253 </pre>
254
255 <p><li> [Apr 2001] <strong>Page 101, Appendix A, <tt>instance Monad IO</tt>.</strong>
256 Replace the definition of <tt>fail</tt> in <tt>instance Monad IO</tt> by
257 <pre>
258 fail s = ioError (userError s)
259 </pre>
260
261 <p><li><strong>Page 102, Appendix A, comments immediately before
262 <tt>instance Enum Float</tt>.</strong>
263 Replace "<tt>1.0</tt>" by "<tt>0.95</tt>".
264
265 <p> <li> [Apr 2001] <strong>Page 105, Appendix A.1, line 11.</strong>
266 In the module header for <tt>PreludeList</tt> replace "<tt>Sum</tt>" by "<tt>sum</tt>".
267
268 <p><li><strong>Page 105, Appendix A.1 (PreludeList), line 19.</strong>
269 Correct the type of <tt>map</tt> to
270 <pre>
271 map :: (a -> b) -> [a] -> [b]
272 </pre>
273
274 <p><li><strong>Page 106, definition of <tt>(!!)</tt>.</strong>
275 Replace the definition of <tt>(!!)</tt> with the following:
276 <pre>
277 -- List index (subscript) operator, 0-origin
278 (!!) :: [a] -> Int -> a
279 xs !! n | n < 0 = error "Prelude.!!: negative index"
280 [] !! _ = error "Prelude.!!: index too large"
281 (x:_) !! 0 = x
282 (_:xs) !! n = xs !! (n-1)
283 </pre>
284 (The original version had the property that <tt>([] !! -100)</tt>
285 reported "index too large".)
286
287 <p><li> [Apr 2001] <strong>Page 107, definition of <tt>scanl1</tt> and <tt>scanr1</tt>.</strong>
288 Replace the definitions of <tt>scanl1</tt> and <tt>scanr1</tt> with these:
289 <pre>
290 scanl :: (a -> b -> a) -> a -> [b] -> [a]
291 scanl f q xs = q : (case xs of
292 [] -> []
293 x:xs -> scanl f (f q x) xs)
294
295 scanl1 :: (a -> a -> a) -> [a] -> [a]
296 scanl1 f (x:xs) = scanl f x xs
297 scanl1 _ [] = []
298
299 scanr1 :: (a -> a -> a) -> [a] -> [a]
300 scanr1 f [] = []
301 scanr1 f [x] = [x]
302 scanr1 f (x:xs) = f x q : qs
303 where qs@(q:_) = scanr1 f xs
304 </pre>
305 The effect is to make both functions defined on the empty list.
306
307
308 <p><li> [Apr 2001] <strong>Page 108, definition of <tt>take</tt>, <tt>drop</tt>, and <tt>splitAt</tt>.</strong>
309 Replace the definitions of <tt>take</tt>, <tt>drop</tt>, and <tt>splitAt</tt> with these:
310 <pre>
311 take :: Int -> [a] -> [a]
312 take n _ | n <= 0 = []
313 take _ [] = []
314 take n (x:xs) = x : take (n-1) xs
315
316 drop :: Int -> [a] -> [a]
317 drop n xs | n <= 0 = xs
318 drop _ [] = []
319 drop n (_:xs) = drop (n-1) xs
320
321 splitAt :: Int -> [a] -> ([a],[a])
322 splitAt n xs = (take n xs, drop n xs)
323 </pre>
324 The effect is that all three functions are defined on negative arguments. This
325 is a semantic change.
326
327 <p><li> [May 2000.] <strong>Page 132, Appendix D, Specification of Derived Instances</strong>.
328 In numbered item 3, replace
329 ``(all constructors must by nullary)'' with
330 ``(all constructors must be nullary)''.
331
332 <p><li> [Apr 2001] <strong>Page 141, Bibliograpy</strong>.
333 Citation [4] should read "JR Hindley".
334
335 <p><li> <strong>Page 141, Bibliograpy</strong>.
336 The library report citation [8] is out of date. It should read:
337 "Simon Peyton Jones and John Hughes (editors), Standard Libraries for the
338 Haskell 98 Programming Language, 1 February 1999".
339
340 <p><li><strong>Page 147, Index</strong>. Remove the entry for "monad comprehension".
341
342 <p><li> [Apr 2001] <strong>Index of the Haskell 98 Prelude (HTML version only)</strong>
343 <ul>
344 <li> Remove <tt>Eval</tt> as a superclass of <tt>Num</tt>
345 <li> Correct type of <tt>seq</tt> to <tt>seq :: a -> b -> b</tt>.
346 </ul>
347 </ul>
348
349 <hr>
350 <h1>Errata in the
351 <a href="http://haskell.cs.yale.edu/definition/">Haskell 98 Library Report</a></h1>
352
353 <ul>
354 <p><li> <strong>Title page</strong>. Add the paragraph:
355 <p>
356 "Copyright (c) Simon Peyton Jones and John Hughes.
357 <p>
358 The authors intend this Report to belong to the entire Haskell
359 community, and so we grant permission to copy and
360 distribute it for any purpose, provided that it is
361 reproduced in its entireity, including this Notice. Modified
362 versions of this Report may also be copied and distributed for any purpose,
363 provided that the modified version is clearly presented as such,
364 and that it does not claim to be a definition of the Haskell 98 libraries."
365
366 <p><li> [Apr 2001] <strong>Page 5, Section 2.1, Library <tt>Ratio</tt></strong>.
367 Replace the definition of <tt>recip</tt> on line 3 by the following
368 <pre>
369 recip (x:%y) = y % x
370 </pre>
371 The effect of this change is to use the "smart constructor", <tt>%</tt>, instead
372 doing it by hand. In particular, an error will be raised if y is zero.
373
374 <p><li> <strong>Page 17, Section 5, first text line</strong>. Replace "continuous" by "contiguous".
375
376 <p><li> [Apr 2001] <strong>Page 19, Section 5.2, comment on <tt>rangeSize</tt></strong>. Replace whole comment by
377 <pre>
378 -- NB: replacing "null (range b)" by "not (l <= h)"
379 -- fails if the bounds are tuples. For example,
380 -- (1,2) <= (2,1)
381 -- but the range is nevertheless empty
382 -- range ((1,2),(2,1)) = []
383 </pre>
384 (This simply fixes a misleading comment.)
385
386 <p><li> [May 2000] <strong>Page 17, Section 5, Indexing operations</strong>.
387 Add the following equation to the laws listed just before Section 5.1:
388 <pre>
389 map index (range (l,u)) == [0..rangeSize (l,u)]
390 </pre>
391 This documents an invariant that was previously only implicit.
392
393 <p><li> [May 2000] <strong>Page 17, Section 5, Indexing operations</strong>.
394 This significant item (a) removes <tt>Ord</tt> from <tt>Ix</tt>'s superclasses, and
395 (b) make <tt>rangeSize</tt> into a method of <tt>Ix</tt> rather than a free-standing declaration.
396 Though these changes are
397 visible to the programmer, all existing Haskell 98 programs will continue to work.
398 <ul>
399 <li> <strong>Page 17, Section 5, Indexing operations, boxed text</strong>. Replace the <tt>Ix</tt>
400 change the class declaration, and the type signature for <tt>rangeSize</tt> with:
401 <pre>
402 class Ix a where
403 range :: (a,a) -> [a]
404 index :: (a,a) -> a -> Int
405 inRange :: (a,a) -> a -> Bool
406 rangeSize :: (a,a) -> Int
407 </pre>
408 <li> <strong>Section 5.2, pages 19, line 3</strong>. Replace the <tt>Ix</tt>
409 class declaration, and the <tt>rangeSize</tt> declaration, with:
410 <pre>
411 class Ix a where
412 range :: (a,a) -> [a]
413 index :: (a,a) -> a -> Int
414 inRange :: (a,a) -> a -> Bool
415 rangeSize :: (a,a) -> Int
416
417 rangeSize b@(l,h) | null (range b) = 0
418 -- NB: replacing "null (range b)" by "not (l <= h)"
419 -- fails if the bounds are tuples. For example,
420 -- (1,2) <= (2,1)
421 -- but the range is nevertheless empty
422 -- range ((1,2),(2,1)) = []
423 </pre>
424 </ul>
425
426 <p><li> <strong>Page 22, Section 6.3; and Page 23, Fig 3</strong>:
427 Replace "<tt>map</tt>" by "<tt>fmap</tt>" (two occurrences in 6.3, one in Fig 3).
428
429 <p><li> [May 2000] <strong>Page 23, Figure 3</strong>.
430 In the definition of <tt>diag</tt>, delete the guard ``<tt>| l==l' &amp;&amp; u==u'</tt>''.
431 (The original intent was presumably to check for a square array, but
432 simply makes the definition recursive and hence divergent.)
433
434 <p><li> <strong>Page 29, Section 7.2</strong>. Add a new bullet for <tt>nub</tt>.
435 Add an index entry for <tt>nub</tt>.
436
437 <p><li> <strong>Page 29, Section 7.2, second bullet</strong>.
438 Introduce a new bullet just before "<tt>union</tt> is list union".
439
440 <p><li> [Apr 2001] <strong>Page 34, Section 7.8, Library List</strong>.
441 Replace the definition of <tt>partition</tt> by
442 <pre>
443 partition :: (a -> Bool) -> [a] -> ([a],[a])
444 partition p xs = (filter p xs, filter (not . p) xs)
445 </pre>
446 This simply makes it agree with the definition on page 30 (Section 7.3).
447
448 <p><li> [Apr 2001] <strong>Page 35, Section 7.8</strong>.
449 Replace the definitions of <tt>maximumBy</tt> and <tt>minimumBy</tt> by the following
450 <pre>
451 maximumBy :: (a -> a -> Ordering) -> [a] -> a
452 maximumBy cmp [] = error "List.maximumBy: empty list"
453 maximumBy cmp xs = foldl1 max xs
454 where
455 max x y = case cmp x y of
456 GT -> x
457 _ -> y
458
459 minimumBy :: (a -> a -> Ordering) -> [a] -> a
460 minimumBy cmp [] = error "List.minimumBy: empty list"
461 minimumBy cmp xs = foldl1 min xs
462 where
463 min x y = case cmp x y of
464 GT -> y
465 _ -> x
466 </pre>
467 <strong>NOTE:</strong> this is a semantic change, but it makes the definitions
468 consistent with the other "By" functions, and with the signatures given on page 28.
469
470 <p><li><strong>Page 54, Section 11</strong>.
471 The signature for <tt>try</tt> should be
472 <pre>
473 try :: IO a -> IO (Either IOError a)
474 </pre>
475
476 <p><li> [Apr 2001] <strong>Page 56-58, Section 11.2, Files and Handles</strong>.
477 Add a section 11.2.3 to clarify the file-locking issue. It says:
478 <p>
479 "Implementations should enforce as far as possible, locally to the
480 Haskell process, multiple-reader single-writer locking on files.
481 That is, there may either be many handles on the same file which manage
482 input, or just one handle on the file which manages output. If any
483 open or semi-closed handle is managing a file for output, no new
484 handle can be allocated for that file. If any open or semi-closed
485 handle is managing a file for input, new handles can only be allocated
486 if they do not manage output. Whether two files are the same is
487 implementation-dependent, but they should normally be the same if they
488 have the same absolute path name and neither has been renamed, for
489 example.
490
491 Warning: the <tt>readFile</tt> operation (Section 7.1 of the Haskell Language Report)
492 holds a semi-closed handle on the file until the entire contents of the file have been
493 consumed. It follows that an attempt to write to a file (using <tt>writeFile</tt>, for example)
494 that was earlier opened by <tt>readFile</tt> will usually result in
495 failure with <tt>isAlreadyInUseError</tt>."
496
497 <p><li><strong>Page 62, Section 11.7.2</strong>.
498 <ul>
499 <li>Add a new section heading "<strong>11.7.3 Reading the entire input</strong>"
500 just before the paragraph about <tt>hGetContents</tt>.
501 <li>
502 Add a new section heading "<strong>11.7.4 Text output</strong>" before the
503 paragraph about <tt>hPutChar</tt>.
504 </ul>
505 <p><li><strong>Page 63, definition of <tt>main</tt> in Section 11.8.1</strong>.
506 Replace the definition of "<tt>readNum</tt>" with
507 <pre>
508 where readNum :: IO Integer
509 -- Need a type signature for readLn to avoid ambiguity
510 readNum = readLn
511 </pre>
512 (This change merely advertises the generally useful function <tt>readLn</tt>.)
513
514
515 <p><li><strong>Page 64, Section 12, Directory functions.</strong>
516 (More an editor's blunder than a typo.)
517 <ul>
518 <li>
519 Replace the abstract definition of <tt>Permissions</tt>, and the four instances
520 of <tt>Permissions</tt> with
521 <pre>
522 data Permissions
523 = Permissions {
524 readable, writable, executable, searchable :: Bool
525 }
526 deriving ( Eq, Ord, Read, Show )
527 </pre>
528 <li> Remove <tt>readable, writable, executable, searchable</tt> both from
529 the module header, and from the module body.
530 <li> Change <tt>Permissions</tt> to <tt>Permissions(readable, writable, executable, searchable)</tt>
531 in the module header.
532 </ul>
533
534 <p><li> [Apr 2001] <strong>Page 78, Section 16, The <tt>CPUTime</tt> library</strong>.
535 Add <tt>cpuTimePrecision</tt> to the export list.
536
537 <p><li>[Apr 2001] <strong>Page 81, Section 17.1, The <tt>RandomGen</tt> class</strong>.
538 This sigificant semantic change adds a method <tt>genRange</tt> to the <tt>RandomGen</tt>
539 class. (Extensive discussion on the Haskell mailing list made it clear that this change
540 is essential to make the RandomGen class useful.) The following summarises the changes
541 but not in the detailed line-by-line form used for the rest of the errata.
542 <ul>
543 <li> Add a method <tt>genRange :: g -> (Int,Int)</tt> to class <tt>RandomGen</tt>.
544 <li> Give it the default method <tt>genRange g = (minBound,maxBound)</tt>
545 <li> Add a specification of <tt>genRange</tt>
546 <li> Change the header on page 80 to match.
547 </ul>
548
549 <p><li>[Apr 2001] <strong>Page 81, Section 17.1, The <tt>RandomGen</tt> class</strong>.
550 Specify more precisely that <tt>split</tt> must deliver <strong>independent</strong> generators.
551
552 <p><li><strong>Page 81, Section 17.1, The <tt>RandomGen</tt> class</strong>.
553 Bottom line on page 81: replace "<tt>show/Read</tt> instances" with
554 "<tt>Show/Read</tt> instances" (i.e. capitalise <tt>Show</tt>).
555
556 <p><li><strong>Page 83, Section 17.3, The global random number generator</strong>.
557 In the first paragraph, replace "kernal" by "kernel".
558
559 </ul>
560 <hr>
561 <address>Simon Peyton Jones, simonpj@microsoft.com</address>
562 </body>
563 </html>
564