 
To report errata in the text, please send email to Paul Hudak at paul.hudak@yale.edu.
To report bugs in the software library, please send email to both Paul Liu at
hai.liu@yale.edu and Paul Hudak at paul.hudak@yale.edu.
Errata
The following errata are listed in the order that they appear in the book,
but they are organized into two groups: those that are technical in
nature, and those that are superficial / typographical.
Technical errors:
 Page 30, first few lines of second proof should read:
area (Polygon [(0,0),(s1,0),(0,s2)])
=> polyArea[(s1,0),(0,s2)]
=> triArea (0,0) (s1,0) (0,s2) + polyArea [(0,s2)]
=> ...
 Page 41, Section 3.2: The type signature for
getKey
is wrong.
It should be:
getKey :: Window > IO Char
 Page 45, top: In the definition of fillTri,
the argument to polygon is a list with identical start and end points.
However, according to the definition of polygon
on page 43, there is no need to "close" the polygon in this way.
Of course, it doesn't hurt that the extra vertex is there, but it would be simpler and slightly more efficient to leave it out.
 Page 49, Exercise 4.2: The question should read: "Why is pixelToInch
not defined as inToFloat (n `div` 100),
where div computes integer division (i.e.
rounds the quotient down)?"
 Page 61, Section 5.2.2:
draw
should be drawInWindow .
So drawShapes
should be:
drawShapes w ((c, s) :
cs)
= do drawInWindow w ...
 Page 62, Section 5.2.2: The type signature for
zip
is wrong. It
should be:
zip :: [a] > [b] > [(a,b)]
The signature shown is actually that for the function zipWith
(see page 75
and Chapter 23).
 Page 68, Section 5.4.2: concat [[1],[3,4],[],[5,6]]
calculates to [1,2,3,4,5,6], but it
should be [1,3,4,5,6].
 Pages 6869: The derivations:
concat [xs1, ..., xsn]
... => xs1 ++ (xs2 ++ (... (xn ++ []))...)
slowConcat [xs1, ..., xsn]
=> (...(([] ++ x1) ++x2) ...) ++xn
contain a few minor typos: x1
should
be xs1, x2
should be xs2, and
xn should be xsn.
 Page 69, 13th line should be: =>
n*(n1)*len/2.
 Page 72, Exercise 5.2: "foldl foldl"
does not have a principal type. Hugs, for example, will complain that
"unification would give infinite type."
 Page 72, Exercise 5.4. Although there is a solution to this problem
using map, flip, and ($), the latter two functions aren't introduced until
pages 107 and 124, respectively.
 Page 73, Exercise 5.9: Note that the straightforward solution to this
problem is not necessarily optimal for all sets of coin values. For example, making change for an amount 6 given coin values [4,3,1] is
better solved as [0,2,0] rather than [1,0,2].
 Page 86, Exercise 7.2: In the definition of "t",
"
Branch 2 t' t' "
should be "IBranch 2 t' t' ".
 Page 86, Exercise 7.3: The function "repeat"
is mentioned, but is not introduced until page 206. Either ignore its
presence, or see its definition on page 206, which is selfcontained.
 Page 96: containsS won't work for RtTriangle s1
s2 when one of s1 and s2
is positive and the other is negative, because then the vertices become ordered clockwise instead of
counterclockwise. The simplest fix is:
RtTriangle s1 s2 `containsS` p
= let vs = if signum s1 == signum s2 then [(0,0),(s1,0),(0,s2)]
else [(0,0),(0,s2),(s1,0)]
in Polygon vs `containsS` p
where signum is a predefined Haskell
function such that signum s is +1
if s is positive, 0
if s is zero, and 1
if s is negative.
 Page 108, Exercise 9.6: appendr
and appendl should have type [[a]] >
[a].
 Page 121, lines 4 and 3 should be:
inchToPixel(lx + x * sx).
and inchToPixel(ly + y * sy)
These errors occur again on page 122 (four times), but on page 123 in the definition of the function
trans everything is correct.
 Page 122, end of page (2nd "Details"): The definition of
trans
is missing arguments lx and ly
on the lefthand side. It should be:
trans sx sy lx ly (x,y) =
...
Furthermore, the righthand side of this
definition and each of the other definitions of
trans
on pages 121 and 122 are wrong. They should be just like the definition
of
trans
on page 123 (within
ShapeToRegion).
 Page 124, Section 10.3.4: There is a comment saying that r4
was derived from sh4 in Section 4.3. Actually the
order of the vertices in the polygon is reversed.
 Page 132, Section 11.2: "Recall in Section 5.1 ..." should read
"Recall in Section 5.4.1 ...".
 Page 137, Section 11.3: In the parenthesized paragraph, the type a
> b should be a > a,
and the type [a] > [b] should
be [a] > [a].
 Page 137 (two occurrences): "Fig.11.1" should be "Table 11.1".
 Page 140: The placement of Figure 11.1 is somewhat confusing: the function f to which it refers isn't defined until page 142, and Figure 11.1
isn't (properly) referenced until page 145.
 Page 151, Section 12.2: IntegerEq
should be integerEq (two
places).
 Page 164, Paragraph 1: Actually, the IO action clearWindow
is used in the code on page 127 (chapter 10). However, it's use was
not necessary for the reason given: each new picture completely hides the
old one.
 Page 177, Section 13.4: The code:
m :: Behavior Picture
m = ...
p :: Picture
p = empty
is followed by the comment:
Details: It is interesting to note that if the two type signatures
above are removed,
then the types of the resulting equations are ambiguous; there is not
enough
information to determine the types uniquely! ...
Actually, without type signatures the code for m and p would
generate an error because of Haskell's monomorphism restriction, but not because of
"ambiguity". In fact, the most general types for m and p
are:
m :: Combine a => Behavior a
p :: Combine a => a
(See the Haskell Report for details on the monomorphism restriction.)
 Page 186: The where clause in the
definition of lifti should be:
... where Beh h = liftj f (Beh b1) ... (Beh bj)
 Page 204, top: This proof only works when n/=0.
When n==0, the proof is as follows:
take 0 __ ++ drop 0 __
=> [] ++ drop 0 __
=> drop 0 __
=> __
The last step of this proof depends on the definition of drop,
which is:
drop 0 xs = xs
drop _ [] = []
drop n (_:xs)  n>0 = drop (n1) xs
 Page 208, Chapter 15: the function reactimate has type:
reactimate :: String > Behavior Graphic > IO ()
whereas in Chapter 17 it has type:
reactimate :: String > Behavior a > (a > IO Graphic)
> IO ()
The differences between the two are minor, but it's probably best to use the one in
Chapter 15. To do so, download the source code for SOE. You will note that the
code for Chapter 15, which is in the file Fal.lhs, is selfcontained and does not
depend on the code in Chapter 17, which is in the file Reactimate.lhs. In
particular, Fal.lhs defines reactimate with the first type
above, which can be used as described in Chapter 15. The description of reactimate in Chapter 17, however, should still be sufficient to
understand the code in Fal.lhs.
 Page 218: the first equation for manyInList
should be:
manyInList [] ys = map (\_ >
False) ys
 Page 226, lines 12 and 13: fmap and Functor are mentioned here, but aren't
defined until Chapter 18.
 Page 240, Section 16.2: In the definition of
getLine' ,
the second parameter to catch
should be:
\err > return ("Error: " ++
show err)
 Page 256: the case statement is not quite
type correct. It should be:
case f x of
Nothing > ...error recovery code...
Just y > case g y of
Nothing > ...error recovery code...
Just z > ...proper result using z...
 Page 257: the typing (>>=) :: [a] > (b > [b]) > [b]
should be:
(>>=) :: [a] > (a > [b]) > [b].
 Page 275, Figure 19.3: pickCoin should not
eraseCoin unless there is only one coin at the current position.
 Page 308, Section 21.2: The definition of equivalence should
read:
(∀c) perform c m1
= perform c m2
 Page 330, Section 23.11: The type of map
is wrong: it should be (a > b) > [a] >
[b].
 Page 325, Section 23.4: The code for span is
wrong. It should be:
span p [] = ([],[])
span p xs@(x:xs')
 p x = (x:ys,zs)
 otherwise = ([],xs)
where (ys,zs) = span p xs'
 Pages 348349, Appendix B: Here an aspattern is said to be
irrefutable, and also has the statement "aspatterns always result in a
successful match". In fact, aspatterns only result in a
successful match if the subterm always results in a successful match.
I.e. the pattern v@pat is
irrefutable only if pat is
irrefutable.
Superficial / typographical errors:
 Page 6, line 3: "('b,'4)" should be "('b',4)".
 Page 29, 13th line: "Pythagorean's theorem" should be "Pythagorean theorem".
 Page 33, Exercise 2.5, 4th line: "trapeziod" should be "trapezoid".
 Page 34, the 'all constructors' abbreviation should be (..),
not (...).
 Page 41 "coodinates" should be "coordinates".
 Page 42, Section 3.3, 1st sentence: "draw"
should be "drawInWindow".
 Page 38, Section 3.1, secondtolast paragraph: "libararies"
should be "libraries".
 Page 63, last line: "hello world" should be "helloworld".
 Page 72, Exercise 5.5, part 2, should read: "Pairs each number in a
list with one plus that number."
 Page 73, Exercise 5.8, under hint: "16bit" should be
"32bit".
 Page 80, last paragraph: "r1 is greater than r2" should be "r1 is greater than or
equal to r2".
 Page 85, line 5: "interprepter" should be "interpreter".
 Page 89, last line, " the rectangle s"
should be "the rectangle square".
 Page 98, Exercise 8.4: "clockwise" should be
"counterclockwise."
 Page 101, line 10: "theorms" should be "theorems".

Page 103, section 8.4, 3rd line: there is a
spurious "=" sign after "rectangle s1 s2".
 Page 106, line 16: "defintions" should be "definitions".
 Page 124, in Details box: ""Region
Test"" should be "s".
 Page 136, line 10: "is" should be "in".
 Page 144, line 4: "tact" should be "tactic".
 Page 158, line 14: "\Eq" should
be "Eq".
 Page 159, last line: Although earlier versions Haskell defined the
function type as an instance of Show,
Haskell 98 does not.
 Page 166, paragraph 1, " although are not" should be
"although not".
 Page 177, line 3: "the the" should be "the".
 Page 185, Exercise 13.5, last point: " multiples pi/2" should be
"multiples of pi/2".
 Page 186, "Beh (K x)" should be
"Beh (k x)".
 Page 187, line 4: "[2..]"
should be "[2,2..]".
 Page 188, line 11: "infinte" should be "infinite".
 Page 198, Details box, line 7: "tfib" should be "tfibs".
 Page 199, last line of code: "fibs" should
be "fibsFn".
 Page 227, line 11: "succesive" should be "successive".
 Page 231, line 3: "step" should be "switch".
 Page 237, line 6: "String"
should be "IO String".
 Page 238, Section 16.1.1: The declaration of FilePath
should appear at the beginning of Section 16.1.
 Page 242, line 9: "infrastruture" should be
"infrastructure".
 Page 244, line 5: "the numbers 1, 2, 3, ..." should read "the numbers 2,
3, 4, ...".
 Page 248, line 4: "makeStreams" should be
"makeStream".
 Page 253, second details box: "string argument to error" should be
"string argument to fail".
 Page 280, lines 6 to 5: "(10,5)" should be "(15,8)" and "(5,10)"
should be "(2,17)".
 Page 285, Exercise 19.2, part 1: Delete "at least once".
 Page 288, line 11: "(A,4)" should be "(A,5)" (to be
consistent with page 295).
 Page 296, line 14: "(/=)" should
be "(/=:)".
 Page 305, line 14: "is" should be "are".
 Page 314, line 6: "that" should be "as".
 Page 337, definition of showList: The definitions of
showChar and showString
are not given; they can be found in the Haskell Report.
 Page 349, line 15: "are" should be "is".
 Page 353, line 11: "P. Walder" should be "P. Wadler".
 Page 355, line 3: "1998" should be "1988".
