Haskell 98 (Revised Report): ERRATA

## Errata in the Revised Haskell 98 Language Report (2003)

The list below gives all known errors in "Haskell 98 Language and Libraries: the Revised Report", published by Cambridge University Press as a book, and also in the Journal of Functional Programming 13(1) (Jan 2003). All page references are to these texts, which may differ slightly from the online versions.

- [Dec 2005] Page 8, Section 2.2, Lexical Program Structure The production for end-of-line comment appears to permit the character sequence `--:` to introduce a comment, although it should properly be permissible as a varsym. The production can be fixed by changing it thus:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

- [Feb 2003] Page 123, Section 8.2, PreludeText. In the definition of `lex` make the following changes:
  - Replace `isAlpha` in the third guard by `isIdInit`.
  - In the definition of `isSingle`, remove the underscore '_' from the quoted list.
  - Add the following local definition:

          isIdInit c = isAlpha c || c == '_'

  [These changes reflect the fact that an identifier can start with an underscore.]

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

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

- [March 2003] Page 170, Chapter 15, Indexing operations. Replace the (bogus) law

        map index (range (l,u)) = [0..rangeSize (l,u)]

  by

        map (index (l,u)) (range (l,u)) = [0 .. rangeSize (l,u) - 1]

- [September 2008] Page 187-188, Chapter 17, List utilities. The "`generic`" functions should behave the same way as the `Prelude` functions for negative arguments. The ones listed in the report call `error`, while the `Prelude` versions simply treat negative numbers as 0. The implementations are replaced by:

      genericTake             :: (Integral a) => a -> [b] -> [b]
      genericTake n _ | n <= 0 = []
      genericTake _ []        =  []
      genericTake n (x:xs)    =  x : genericTake (n-1) xs

      genericDrop             :: (Integral a) => a -> [b] -> [b]
      genericDrop n xs | n <= 0 = xs
      genericDrop _ []        =  []
      genericDrop n (_:xs)    =  genericDrop (n-1) xs

      genericSplitAt          :: (Integral a) => a -> [b] -> ([b],[b])
      genericSplitAt n xs | n <= 0 =  ([],xs)
      genericSplitAt _ []     =  ([],[])
      genericSplitAt n (x:xs) =  (x:xs',xs'') where
          (xs',xs'') = genericSplitAt (n-1) xs

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

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

- [July 2003] Index to the online version (only).
  - The type for `either` is missing.
  - The type for `print` should be

           print :: Show a => a -> IO ()

  - [Oct 2006] The example usage of `break` is wrong. A correct example might be

            break (>2) [1,2,3] == ([1,2],[3])

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