# Miranda Book - Corrigenda

Despite our best efforts, "Programming with Miranda" has (too) many errors which survived the proof-reading process. This page details these errors and suggests corrections.

• On page 16, the following example has a transcription error:
```	Miranda 3 ^ 3
9
```

It should, of course, have been printed as:

```	Miranda 3 ^ 3
27
```

Don't worry - Miranda gives the correct result!

• On page 28, the sentence "In Miranda, all operators (except for ++ -- and :, as will be seen in Chapter 3)" is incorrect. The exponentiation operator ^ is also right associative.
• On page 39, we say that a function argument is only evaluated when it is required, and we say this is sometimes known as "call-by-name". It would be more accurate to say that it is sometimes known as "call-by-reference". However, a discussion of the difference between "call-by-name", "call-by-reference" and "call-by-need" is probably beyond the scope of this book. The reader should simply note that the argument to a function will not be evaluated if it is not required for the function to return the correct result.
• In Chapter 2, on page 46, Exercise 2.4 refers to "both versions of the function solomonGrundy", whereas only one version is given in the text. Similarly, on page 48 the text refers to "the second version of the solomonGrundy function".

The "second version" is the version that is given in the text - it uses pattern matching. Originally there was also a version which used conditional guards: this has been removed. The solution to this exercise (on page 268) provides example code for both versions. Unfortunately the conditional version given in the solutions is, although syntactically correct, not very pretty: it is not necessary to repeat the function name and the parameter name for each conditional clause.

• In the Solutions to Exercises on page 270 there is a misprint: in the function definition for int_divide please replace
```	= - (posdiv (-n, -m)), if n < 0
```
with
```	=  - (posdiv (-n, m)), if n < 0
```
• On page 56 the following transition:
```	==> "." ++ ("." ++ (printdots (2-1)))

==> "." ++ ("." ++ ("." ++ (printdots 1)))
```
should be replaced by the transition:
```	==> "." ++ ("." ++ (printdots (2-1)))

==> "." ++ ("." ++ (printdots 1))
```
• On page 61 (and page 270 where the question is repeated) exercise 2.9 is slightly ambiguous. Here is a better wording:

"Write a function called int_divide which divides one whole number by another; the function should not use any arithmetic operators except for subtraction, addition and unary minus."

• At the bottom of page 77, there is a sentence that introduces a list of three things by saying "There are four things that can appear ...". In retrospect, the introductory sentence and the list in its entirety might be better expressed as follows:
```Where a function takes a list parameter, that parameter can be matched against one of the following patterns:

1. A formal parameter name, which matches any actual value - for example, x
2. A constant list value - for example, [] or [1,2]
3. A list in aggregate form containing names and/or constants - for example, [x, y, 34]
4. A constructed list using : notation and parameter names and/or constants - for example, (x : xs), (3:xs) or (1:(2:rest))
5. A combination of the above - for example, (x : [3,4])
```
(Thanks to Zak Walters for spotting this!).
• On page 89, Exercise 3.10, the example given uses a [[char]] whereas when the question is repeated in the solutions (on page 274) the example uses a [char]. This of course is not a very serious difference, since the function as defined is polymorphic and so both examples are correct!
• On page 91, we really should have included the type for the function isort:
```	isort :: nlist -> nlist
```
• On page 93, the first word of the first sentence should be "This" rather than "Thi".
• On page 115, the first line hasd a missing bracket. The expression:
```((+ 2) . (* 3) 3
```
should be:
```((+ 2) . (* 3)) 3
```
(Thanks to Andrew Taylor for spotting this one).
• On page 143, in Figure 5.4, the type expression for split is wrong. The code currently says:
```split :: [*] -> ([*], [*])
```
But it should be:
```split :: (* -> bool) -> [*] -> ([*], [*])
```
(Thanks to Hirsh Jaykrishnan Pithadia for spotting this one).
• On page 273, in the solution to Exercise 3.6 there is an error in the condition for the general case of the function listmax. The code says:
```listmax (front : next : rest)
= listmax (front : rest), if front > rest
= listmax (next : rest), otherwise
```
Whereas it should be:
```listmax (front : next : rest)
= listmax (front : rest), if front > next
= listmax (next : rest), otherwise
```
• On page 273, in the solution to Exercise 3.9, there are two errors in type declarations. The phrase:
```	The type of the function is:

(num, [*] -> [*])
```
should be:
```	The type of the function is:

(num, [*]) -> [*]
```
Similarly, at the bottom of the page:
```	The final code is:

(num, [*] -> [*]
```
should be:
```	The final code is:

(num, [*]) -> [*]
```
• On pages 103 and 147 of the book, the type synonyms have an error:
```	regtype == mtype * string
```
```	regtype == (mtype, string)
```
The correct type synonym in all cases should be:
```	regtype == (mtype, char)
```
(Thanks to Hefin Jones for spotting this one).
• On page 103, the code for lex has an error:
```	lex [] = [] = []
```
should be:
```	lex [] = []
```
• On page 95, we refer to "the function mymember in Section 3.6.1". This should read "the function mymember in Section 3.6".
• On page 98, we refer to "Table 3.9". This should, of course, read "Table 3.1".
• On page 98, we give an example of using grep as a UNIX tool. Of course, if this is typed at the UNIX prompt then the strings need not be enclosed in quotes.
• On pages 146 and 147 the type of "oklength" should be:
```oklength :: [*] > num -> num -> bool
```
(spotted by Hefin Jones)
• In Chapter 5, at the top of page 155, there is a definition for the function called make_index_pairs, which contains a where block. In the where block there is a definition of the function called makepairs. The definition of makepairs should be:
```makepairs n [] = []
makepairs n (front2 :  rest2)
= (n, front2) :  (makepairs (n + 1) rest2)
```
But sadly the first line of the function definition is missing the equals sign "=". (spotted by Josh Hale).
• In Chapter 5, starting on page 161, the example of finding prime numbers where a filter is used with the condition of (0 =).(mod x) is wrong. The condition should be (0 ~=) instead of (0 =). This occurs in three places: primes12 and nth_prime n on page 161 and nth_prim n on page 163.

Thus, on page 161 we should have:

```primes12 = selectors generator
where
generator  = [2..1000]
selectors  = ((!12) . (foldr sieve []))
sieve x [] = [x]
sieve x any
= x : (filter ((0 ~=).(mod x)) any)
```
and
```nth_prime n = selectors generator
where
generator  = [2..]
selectors  = ((!n) . (foldr sieve []))
sieve x [] = [x]
sieve x any
= x : (filter ((0 ~=).(mod x)) any)
```
and on page 163 we should have:
```nth_prime n = selectors generator
where
generator   = [2..]
selectors   = ((!n) . (foldr sieve []))
sieve x any = x : (filter ((0 ~=).(mod x)) any)
```
The accompanying text appears to be correct! (spotted by Yazhe Li)
• In Chapter 7, on page 200, there is a block of text near the bottom defining the general rules for showing abstract data types. The existing text says:
```if foo is polymorphic in two type variables (foo * **)

showfoo :: (∗− >[char]) − > (∗ ∗ − >[char]) -> foo ∗ ∗ ∗− > [char]
```
Unfortunately the printing of the spaces is wrong. This is what it should look like:
```if foo is polymorphic in two type variables (foo * **)

showfoo :: (∗ −> [char]) −>  (∗∗  −> [char]) -> foo ∗ ∗∗ −> [char]
```
• On page 225 in the example the definition of confirm is wrong. The opening square bracket in the function body should include (i.e. be to the left of) Stdout.
• On page 224 the "wrongloop" example function is wrong in many ways; this diverts attention from the "wrongness" which it was intended to examplify! Here's a better "wrong" version:
```        wrongloop ip = Stdout msg : System "date"
: Stdout prompt : (rest ip)
where
rest []     = [Stdout "\nGoodbye\n"]
rest (x:xs) = wrongloop xs
```
• On page 224 the "loop" example does not quite work as expected because it assumes UNIX is in cbreak mode (this is briefly covered later in the chapter). If UNIX is not in cbreak mode, the user must press the Return key before the input will be sent to the program; this is then seen by the program as TWO characters (whatever key was pressed, plus the return character '\n') The example could be modified as follows:
```        loop []              = [Stdout "\nGoodbye"]
loop ('\n':rest)     = Stdout ("Please press just one character,"
++ " followed by the Return key")
: (loop rest)
loop (any:'\n':rest) = Stdout msg : System "date"
: Stdout prompt : (loop rest)
loop (any:rest)      = Stdout ("Please press just one character,"
++ " followed by the Return key")
: (loop rest)
```
• In the Solutions to Exercises (solution to exercise number 3.10 on page 275) the solution is given as:
```fromto :: (num,num,[*]) -> [*]
fromto (m, n, alist) = mydrop (m, mytake (n,alist))
```
Whereas in fact the correct solution should be:
```fromto :: (num,num,[*]) -> [*]
fromto (m, n, alist) = mydrop (m, mytake ((n+1),alist))
```
(Thanks to Kimeshan Naidoo for spotting this one!).
• In the Solutions to Exercises (solution to exercise number 3.11 on page 275) the solution is given as:
```stringtostring == [char] -> [char]

skipbrackets :: stringtostring
skipbrackets [] = []
skipbrackets ('(' : rest) = skipbrackets (inbrackets rest)
skipbrackets (front : rest) = front : skipbrackets rest

inbrackets :: stringtostring
inbrackets (')' : rest) = rest
inbrackets ('(' : rest) = inbrackets (inbrackets rest)
inbrackets (front : rest) = inbrackets rest
```
Whereas in fact the correct solution should be:
```stringtostring == [char] -> [char]

skipbrackets :: stringtostring
skipbrackets [] = []
skipbrackets ('(' : rest) = skipbrackets (inbrackets rest)
skipbrackets (front : rest) = front : (skipbrackets rest)

inbrackets :: stringtostring
inbrackets []           = error "no matching bracket"
inbrackets (')' : rest) = rest
inbrackets ('(' : rest) = inbrackets (inbrackets rest)
inbrackets (front : rest) = inbrackets rest
```
(Thanks to Sia Agarwal for noticing this mistake).
• In the Solutions to Exercises (solution to exercise 4.17 on page 284) the function foldiftrue is in two places given the type:
```foldiftrue :: (* -> bool) -> (* -> ** -> **) -> ** -> [*]
```
Whereas in fact the type is:
```foldiftrue :: (* -> bool) -> (* -> ** -> **) -> ** -> [*] -> **
```
(thanks to Chun-Wei (Sarah) Hsu for spotting this mistake!)
• In the Solutions to Exercises (solution to exercise 5.3 on page 286) the solution is given as:
```filter :: (* -> bool) -> [*] -> [*]
filter pred anylist = [x <- anylist | pred x]
```
Whereas in fact the correct solution should be:
```filter :: (* -> bool) -> [*] -> [*]
filter pred anylist = [x | x <- anylist ; pred x]
```
(Thanks to Ben Kremer for spotting this one!).
• In the Solutions to Exercises (solution to exercise number 7.1) a function is given for testing the equality of two natural numbers. The solution incorrectly gives the following code for comparing the equality of (Succ x) and (Succ y):
```	equalNat (Succ x) (Succ y) = x = y
```
Of course, this is wrong - the built-in equality operator "=" cannot be used on values of an abstract type. The code for the above pattern should actually be:
```	equalNat (Succ x) (Succ y) = equalNat x y
```