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.
Miranda 3 ^ 3 9
It should, of course, have been printed as:
Miranda 3 ^ 3 27
Don't worry - Miranda gives the correct result!
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.
= - (posdiv (-n, -m)), if n < 0with
= - (posdiv (-n, m)), if n < 0
==> "." ++ ("." ++ (printdots (2-1))) ==> "." ++ ("." ++ ("." ++ (printdots 1)))should be replaced by the transition:
==> "." ++ ("." ++ (printdots (2-1))) ==> "." ++ ("." ++ (printdots 1))
"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."
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!).
isort :: nlist -> nlist
((+ 2) . (* 3) 3should be:
((+ 2) . (* 3)) 3(Thanks to Andrew Taylor for spotting this one).
split :: [*] -> ([*], [*])But it should be:
split :: (* -> bool) -> [*] -> ([*], [*])(Thanks to Hirsh Jaykrishnan Pithadia for spotting this one).
listmax (front : next : rest) = listmax (front : rest), if front > rest = listmax (next : rest), otherwiseWhereas it should be:
listmax (front : next : rest) = listmax (front : rest), if front > next = listmax (next : rest), otherwise(Thanks to Aditya Pradhan for spotting this one).
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, [*]) -> [*]
regtype == mtype * stringSadly, the online version also had an error (now fixed):
regtype == (mtype, string)The correct type synonym in all cases should be:
regtype == (mtype, char)(Thanks to Hefin Jones for spotting this one).
lex [] = [] = []should be:
lex [] = []
Miranda map_two (make_curried max) [1,2,3] [3,2,1]But the function maxnum (defined previously on Page 117) should have been used instead:
Miranda map_two (make_curried maxnum) [1,2,3] [3,2,1](spotted by Patryk Wloch).
oklength :: [*] > num -> num -> bool(spotted by Hefin Jones)
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).
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)
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](spotted by Aditya Mukherjee).
wrongloop ip = Stdout msg : System "date" : Stdout prompt : (rest ip) where rest [] = [Stdout "\nGoodbye\n"] rest (x:xs) = wrongloop xs
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)
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!).
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 restWhereas 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).
foldiftrue :: (* -> bool) -> (* -> ** -> **) -> ** -> [*]Whereas in fact the type is:
foldiftrue :: (* -> bool) -> (* -> ** -> **) -> ** -> [*] -> **(thanks to Chun-Wei (Sarah) Hsu for spotting this mistake!)
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!).
equalNat (Succ x) (Succ y) = x = yOf 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