The errata list is a list of errors and their corrections that were found after the product was released.
The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.
Version |
Location |
Description |
Submitted by |
Date submitted |
|
??
3rd block of code in "15.4.1. Supplying Random Numbers" |
Error messages about the ambiguous calls. The text indicates the random numbers should be there.
|
Maciej Piechotka |
Apr 14, 2009 |
Printed |
Page Index
Index |
Consider adding the word "composition" to the index. Also, "function composition" should be added (or "composition" as a sub topic under "functions".) These should probably point to page 105, "Code Reuse Through Composition".
|
Mike Depot |
Apr 17, 2010 |
Other Digital Version |
ch8.5
Under globToRegex' definition |
Our first clause stipulates that if we hit the end of our
glob pattern (by which time we'll be looking at the empty
string), we return $, the regular expression symbol for
"match end-of-line."
Not true. The "first clause" returns the empty string, not "$". That maybe the way it was originally but refactored the "$" into the PARENT or CALLING function (the non-prime globToRegex).
|
Anonymous |
Oct 06, 2010 |
Other Digital Version |
ch24
ch24/Sorting.hs |
The parSort method is parenthesized incorrectly. The version given works, but does not gain any speed from parallelism (which is the topic of this chapter). Where the code has
force greater `par` (force lesser `pseq` (lesser ++ x:greater))
it should have:
((force greater) `par` (force lesser)) `pseq` (lesser ++ x:greater)
The corrected version forces both halves to be sorted before the concatenation.
|
Peter Drake |
May 21, 2014 |
Printed |
Page 28
add.hs example after the 1st paragraph |
The comment is
-- file: ch03/add.hs
But actually, the example is given in chapter 2.
And I think the comment should be "-- file: ch02/add.hs"
|
Hongzhi Song |
Feb 07, 2014 |
Printed |
Page 38
In "Reasoning About Polymorphic Functions" |
In the third paragraph it says "nor can it turn an a into a b". While this is correct, it certainly irrelevant for fst. It should probably read "nor can it turn a b into an a", because fst's result type is a.
|
Gabor Greif |
Apr 12, 2009 |
Printed |
Page 41
code definition of BookInfo and examples using it on page 42 |
The data definition of BookInfo uses type Int which is not able to represent the 13 digit ISBN number used in the example on page 42 (as least on 32 bit machines):
ghci> 9780135072455 :: Int
494539463
Type Integer should have been used.
|
Steve Pretty |
Feb 27, 2011 |
Printed |
Page 42
3rd code example from the bottom |
Using latest GHC through ubuntu 32 bit system. The type defines the number of the Book type as Int. However, the number is far too large for a 32 bit platform. It will end up wrapping to 494539463. This can be fixed by declaring the types to use Integer rather then Int to make sure it is true on all platforms.
|
Thomas Tickle |
Jun 18, 2009 |
Printed |
Page 43
code in "Naming Types and Values |
Since we later replace "String" by "ReviewBody" in the next page, it makes more sense to use "Int" in stead of "CustomerID", and have it replaced on the next page as well.
A new comment, in place of the existing one would read:
-- Int is for customer's ID, and String is for the review body
Also, it might be better to reference these "objects" by either their ID number, or by themselves, not both.
Here, each book review holds the entire BookInfo value, but only the ID of the customer (assuming there is a CustomerInfo value as well).
It is a mix of styles.
It would be better if it just held the ID of the BookInfo, or the entire CustomerInfo.
|
Thanos Tsouanas |
Jan 11, 2009 |
Printed |
Page 43
1st paragraph |
It's rare that a variable name is so non-descriptive that anyone would consider it an error, but in this case the variable name 'cities' is such a poor choice of a variable name in this code:
ghci> let cities = Book 173 "Use of Weapons" ["Iain M. Banks"]
I think it should be considered an error. Naming a Book 'cities' is so out of place that it rattles the reader's confidence in the authors.
It's mentioned again on p. 56 in the 3rd code example.
|
7stud |
Feb 28, 2009 |
Printed |
Page 49
1st block of code |
Definition of struct vector is missing in C code.
Should add:
struct vector {
double a;
double b;
}
|
zolli |
Apr 16, 2010 |
Printed |
Page 57
first three paragraphs |
When the following example, on page 57, is entered, using GHCI, the error message shown below is issued...
A fix to get rid of this error worked but then a subsequent error occurs...see the following once again:
--original code:
-- ch03/Nullable.hs
data Maybe a = Just a
| Nothing
someBool = Just True
--someBool = Main.Just True
someString = Just "somethng"
--someString = Main.Just "somethng"
********************************************************************
if this is loaded -- see following load command and error msg:
ghci>:load ch03/nullable
[1 of 1] Compiling Main ( ch03\nullable.hs, interpreted )
ch03\nullable.hs:5:11:
Ambiguous occurrence `Just'
It could refer to either `Main.Just', defined at ch03\nullable.hs:2:15
or `Prelude.Just', imported from Prelude
ch03\nullable.hs:8:13:
Ambiguous occurrence `Just'
It could refer to either `Main.Just', defined at ch03\nullable.hs:2:15
or `Prelude.Just', imported from Prelude
Failed, modules loaded: none.
ghci>
*********************************************************************
If the following correction is made, the load is successful - however, the example in the third paragraph now fails:
-- ch03/Nullable.hs
data Maybe a = Just a
| Nothing
--someBool = Just True
someBool = Main.Just True
--someString = Just "somethng"
someString = Main.Just "somethng"
**********************************************************************
ghci>:load ch03/nullable
[1 of 1] Compiling Main ( ch03\nullable.hs, interpreted )
Ok, modules loaded: Main.
ghci>
**********************************************************************
Now the following error msg is encountered:
ghci>Just 1.5
<interactive>:1:0:
Ambiguous occurrence `Just'
It could refer to either `Main.Just', defined at ch03\nullable.hs:2:15
or `Prelude.Just', imported from Prelude
|
patrick lynch |
Aug 27, 2009 |
Printed |
Page 57
first three paragraphs |
When the following example, on page 57, is entered, using GHCI, the error message shown below is issued...
A fix to get rid of this error worked but then a subsequent error occurs...see the following once again:
--original code:
-- ch03/Nullable.hs
data Maybe a = Just a
| Nothing
someBool = Just True
--someBool = Main.Just True
someString = Just "somethng"
--someString = Main.Just "somethng"
********************************************************************
if this is loaded -- see following load command and error msg:
ghci>:load ch03/nullable
[1 of 1] Compiling Main ( ch03\nullable.hs, interpreted )
ch03\nullable.hs:5:11:
Ambiguous occurrence `Just'
It could refer to either `Main.Just', defined at ch03\nullable.hs:2:15
or `Prelude.Just', imported from Prelude
ch03\nullable.hs:8:13:
Ambiguous occurrence `Just'
It could refer to either `Main.Just', defined at ch03\nullable.hs:2:15
or `Prelude.Just', imported from Prelude
Failed, modules loaded: none.
ghci>
*********************************************************************
If the following correction is made, the load is successful - however, the example in the third paragraph now fails:
-- ch03/Nullable.hs
data Maybe a = Just a
| Nothing
--someBool = Just True
someBool = Main.Just True
--someString = Just "somethng"
someString = Main.Just "somethng"
**********************************************************************
ghci>:load ch03/nullable
[1 of 1] Compiling Main ( ch03\nullable.hs, interpreted )
Ok, modules loaded: Main.
ghci>
**********************************************************************
Now the following error msg is encountered:
ghci>Just 1.5
<interactive>:1:0:
Ambiguous occurrence `Just'
It could refer to either `Main.Just', defined at ch03\nullable.hs:2:15
or `Prelude.Just', imported from Prelude
|
patrick lynch |
Aug 27, 2009 |
Printed |
Page 63
'The where Clause' section |
I ran the example and got the following Load error...
ghci>:load ch03/lending
[1 of 1] Compiling Main ( ch03\lending.hs, interpreted )
ch03\lending.hs:12:4: parse error on input `newBalance'
Failed, modules loaded: none.
*****************************************************************
This is the code:
-- file: ch03/Lending.hs
lend amount balance = let reserve = 100
newBalance = balance - amount
in if balance < reserve
then Nothing
else Just newBalance
lend2 amount balance = if amount < reserve * 0.5
then Just newBalance
else Nothing
where reserve = 100
newBalance = balance - amount
*********************************************************************
|
patrick lynch |
Aug 28, 2009 |
Printed |
Page 65
Code example Indentation.hs |
I was confused by the comment "we reduce the indentation, so this is a new definition." Eventually I saw what you meant: you are reducing it compared to the "continuation blah" line in firstDefinition. But initially it made no sense, as "continuation yada" has the same indentation as "yada yada", i.e. it's not "reduced" compared to that -- which I think is the most obvious comparison to make.
|
david.m.carter |
Apr 09, 2009 |
ePub |
Page 66
4th paragraph |
"Even though the number of elements and their types is the same," should read "Even though the number of elements and their types are the same,"
|
John Claus |
Apr 28, 2015 |
Printed |
Page 71
start of source code at bottom of page, and similar uses through page 75 |
I think "Interact.hs" and "./Interact" are intended to be "InteractWith.hs" and "./InteractWith" for consistency or vice versa.
Even better, I think, would be changing these to "Copy.hs" and "./Copy" (or "copy" or even just "cp".) These names provide indication of what the program actually does. It is odd to type "./InteractWith" when copying a file. Also changing to "Copy" would make the naming more parallel with the sensibly named "FixLines" in the next section.
|
Peter Michaux |
Jul 05, 2009 |
Printed |
Page 72
3rd code sample |
The 3rd code sample uses the executable "./Interact" while it was compiled as "InteractWith" in the 2nd code sample.
Note: on p. 71 the comment in the code sample says
-- file: ch04/InteractWith.hs
-- Save this in a source file, e.g. Interact.hs
which might have to do with the confusion. I'd suggest to drop the second comment line.
|
Thorsten Seitz |
Jan 04, 2009 |
Printed |
Page 72
3rd paragraph |
On Windows PCs the following differences were noted:
[note: $./Interact should be InteractWith - this was noted in a separate errata - this occurs in two places].
1. ./Interact should simply be
Interact [or more correctly InteractWith]
2. ./Interact hello-in.txt hello-out.txt should simply be
Interact hello-in.txt hello-out.txt
3. cat hello-in.txt should be type hello-in.txt
4. cat hello-out.txt should be type hello-out.txt
[note: cat is not a valid PC DOS command].
|
patrick lynch |
Jan 24, 2011 |
Printed |
Page 72
3rd paragraph |
On Windows PCs the following differences were noted:
[note: $./Interact should be InteractWith - this was noted in a separate errata - this occurs in two places].
1. ./Interact should simply be
Interact [or more correctly InteractWith]
2. ./Interact hello-in.txt hello-out.txt should simply be
Interact hello-in.txt hello-out.txt
3. cat hello-in.txt should be type hello-in.txt
4. cat hello-out.txt should be type hello-out.txt
[note: cat is not a valid PC DOS command].
|
patrick lynch |
Jan 24, 2011 |
Printed |
Page 74
Last line |
The second last line reads
"This gives us pre bound to "foo", and suf bound to "bar"."
However, it seems like it should be that "suf" is bound to "\r\nbar" and "rest" is bound to "bar".
|
Anonymous |
Dec 24, 2008 |
PDF |
Page 88
1st line |
"square on the remainder of the empty list." should be "square on the remainder of the nonempty list."
|
Anonymous |
Jan 01, 2011 |
Printed |
Page 94
middle of page |
Here are the two fold examples the text refers to:
foldl (+) 0 (1:2:3:[])
== foldl (+) (0 + 1) (2:3:[])
== foldl (+) ((0 + 1) + 2) (3:[])
== foldl (+) (((0 + 1) + 2) + 3) []
== (((0 + 1) + 2) + 3)
foldr (+) 0 (1:2:3:[])
== 1 + foldr (+) 0 (2:3:[])
== 1 + (2 + foldr (+) 0 (3:[])
== 1 + (2 + (3 + foldr (+) 0 []))
== 1 + (2 + (3 + 0))
The book says on p.94:
-----
The difference between foldl and foldr should be clear from looking at where
the parentheses and the empty list elements show up. With foldl, the empty
list element is on the left, and all the parentheses group to the left.
------
The only empty lists I see in both examples are on the right.
The book continues:
---
With foldr, the zero value is on the right, and the parentheses group to the
right.
----
In the text, 'zero' is bolded to indicate it is a variable name. Presumably, the step function is constantly altering the value of the zero variable, so saying "the" zero value is on the right seems incorrect to me. I think that should read "the initial zero value is on the right".
|
7stud |
Mar 14, 2009 |
Printed |
Page 102
middle |
"Partial function application is named currying, ..." I think this is incorrect. Currying and partial function application are different things. It would be good to disentangle them here.
|
Richard Kelsall |
Apr 12, 2009 |
PDF |
Page 110
2nd paragraph |
"Consider the value (1+2):(3+4):[], If we apply seq to this, it will evaluate the (1+2) thunk."
Not True. It will evaluate the expression as (thunk1 : thunk2). (1+2) is not evaluated, nor is the right thunk.
Further on, the paragraph correctly states that (1+2):(3+4):[] and ((1+2),(3+4)) behave in the same manner when it comes to applying seq, but due to the error above, the following phrase is confusing:
"The same is true for tuples: seq ((1+2), (3+4)) True will do nothing to the thunks inside the pair, since it inmediately hits the pair's constructor."
|
Alfonso Acosta |
Jan 05, 2009 |
Printed |
Page 110
2nd paragraph |
On page 110, 2nd par it is said that applying seq to (1+2):(3+4):[] will evaluate the (1+2) thunk. This is no correct, as (1+2):(3+4):[] is already in HNF. This can be verified using GHCI:
Prelude> ( (undefined+2) : (3+4) : [] ) `seq` True
True
|
pepe Gallardo |
Mar 30, 2009 |
Printed |
Page 111
third paragraph |
The already published errata is wrong.
the plural of "type of value" is "types of value", not "types of values", so the book is right in the first place.
|
Enrico Maria De Angelis |
May 03, 2020 |
PDF |
Page 115
2nd line |
The first non-commented line of file ch05/Main.hs should be
module Main where
|
Anonymous |
Feb 10, 2012 |
Printed |
Page 115
second line from the top |
module Main () where
should be
module Main (main) where
or at least
module Main where
|
Enrico Maria De Angelis |
Apr 30, 2020 |
Printed |
Page 119
several |
Page 119 says that module Prettify will contain "text", "double", and "string" functions (line after first code block; line 5 in last para before second code block; and the signatures in the second code block itself).
However, it seems function "string" does not belong in Prettify. Page 120-122 shows in great detail how to write a function named "string" in module PrettyJSON. The function described is rather JSON-specific, so that makes more sense. Furthermore, the import list from Prettify on page 124 does not mention any function "string".
|
Marcus Uneson |
Mar 08, 2010 |
Printed |
Page 130
3rd para, line 2 |
The values of width and col are 0 and 2, respectively ->
The values of width and col are 2 and 0, respectively
|
Marcus Uneson |
Mar 08, 2010 |
Printed |
Page 131
Start of page |
The signature proposed in Exercise 1 is a copy of the one proposed in Exercise 1.
|
J.A.Zaratiegui |
Jan 01, 2009 |
Printed |
Page 131
1st and 4th paras |
Para 1 says "a package contains one library", while para 4 refers to "every library ... in the package". This leaves me confused about whether or not a package can contain more than one library.
|
david.m.carter |
Apr 09, 2009 |
Printed |
Page 131
exercise at top of the page |
This function probably should be named "nest" instead of "fill".
|
Gabor Greif |
Jun 18, 2009 |
Printed |
Page 133
last paragraph in bullet point (1) |
After showing how to install packages globally with
$ runghc Setup configure
it goes on to mention that "To install it into our home directory and our personal package database, we must provide a little more information:" but then just moves on to the next step without saying what "more information" is. According to the online version at
http://book.realworldhaskell.org/read/writing-a-library-working-with-json-data.html
the missing command is
$ runghc Setup configure --prefix=$HOME --user
|
enoksrd |
Feb 05, 2009 |
Printed |
Page 133
3) at bottom of page |
In step 3) the install command is missing. The online version of the book lists the install command as:
$ runghc Setup install
That tries to install in /usr/local so I got the error:
$ runghc Setup install
Installing: /usr/local/lib/mypretty-0.1/ghc-6.8.2
Setup: /usr/local/lib/mypretty-0.1: createDirectory: permission denied (Permission denied)
So I used sudo:
$ sudo runghc Setup install
After installing, you can issue the command
$ ghc-pkg list
/usr/local/lib/ghc-6.8.2/package.conf:
Cabal-1.2.3.0, GLUT-2.1.1.1, HUnit-1.2.0.0, OpenAL-1.3.1.1,
OpenGL-2.2.1.1, QuickCheck-1.1.0.0, array-0.1.0.0, base-3.0.1.0,
bytestring-0.9.0.1, cgi-3001.1.5.1, containers-0.1.0.1,
directory-1.0.0.0, fgl-5.4.1.1, filepath-1.1.0.0, (ghc-6.8.2),
haskell-src-1.0.1.1, haskell98-1.0.1.0, hpc-0.5.0.0, html-1.0.1.1,
mtl-1.1.0.0, mypretty-0.1, network-2.1.0.0, old-locale-1.0.0.0,
old-time-1.0.0.0, packedstring-0.1.0.0, parallel-1.0.0.0,
parsec-2.1.0.0, pretty-1.0.0.0, process-1.0.0.0, random-1.0.0.0,
readline-1.0.1.0, regex-base-0.72.0.1, regex-compat-0.71.0.1,
regex-posix-0.72.0.2, rts-1.0, stm-2.1.1.0,
template-haskell-2.2.0.0, time-1.1.2.0, unix-2.3.0.0,
xhtml-3000.0.2.1
And you should be able to locate your package in there: mypretty-0.1.
Of course, the book doesn't say what installing a package does for you. What good is it? How do you access it?
|
7stud |
Mar 27, 2009 |
Printed |
Page 136
Start of "What are typeclasses?" |
I would replace "Typeclasses define" with "A typeclass defines". The former could be read by the novice as "Between them, typeclasses define a set of functions..." -- so maybe only one function per typeclass, for all they know.
|
david.m.carter |
Apr 11, 2009 |
Printed |
Page 149
2nd code example |
The comment in the sample indicates that this code will not compile, because CannotShow is not an instance of Show:
data CannotShow = CannotShow
deriving (Show)
-- will not compile, since CannotShow is not an instance of Show
data CannotDeriveShow = CannotDeriveShow CannotShow
deriving (Show)
However, CannotShow *is* an instance of Show, because of the deriving directive. For this code not to compile, the deriving directive of CannotShow should be removed.
|
Vincent Foley |
Dec 14, 2008 |
Printed |
Page 149
Example of automatic derivation |
The example is incorrect:
data CannotShow = CannotShow
deriving (Show)
-- will not compile, since CannotShow is not an instance of Show
data CannotDeriveShow = CannotDeriveShow CannotShow
deriving (Show)
This will compile nicely, however. I think the deriving (Show) declaration in CannotShow should be removed to correctly illustrate the problem.
|
David Fries |
Feb 05, 2009 |
Printed |
Page 149
Sample |
you have data
CannotShow = CannotShow deriving (Show);
This is supposed to be lacking "deriving (Show)"
This means CannotDeriveShow's CannotShow is deriving show -- and subsequently, it does compile, even though the book says explicitly it won't compile.
|
Evan Carroll |
Jan 25, 2010 |
Printed |
Page 149
3rd lin of 2nd code block |
The 3rd line should be removed because compile error doesn't occur.
|
Nellie McKesson |
May 24, 2011 |
Printed |
Page 149
Second Code Example -- ch06/AutomaticDerivation.hs |
The example reads:
data CannotShow = CannotShow
deriving (Show)
-- will not compile, since CannotShow is not an instance of Show
data CannotDeriveShow = CannotDeriveShow CannotShow
deriving (Show)
However, because of the first 'deriving (Show)', it is in fact the case that CannotShow is an instance of Show, and therefore CannotDeriveShow can in fact derive Show with no problem.
It appears that the first 'deriving (Show)' was left in unintentionally.
|
Kyle Pointer |
Jun 09, 2015 |
Printed |
Page 150
1st line of middle paragraph |
Because Haskell doesn't natively support lists that contain types of
different values,
should be
Because Haskell doesn't natively support lists that contain values of
different types,
|
Nellie McKesson |
May 24, 2011 |
Printed |
Page 153
1st code block |
FlexibleInstances language extension is required to compile this code.
We will get following errors without this extension.
Illegal instance declaration for `JSON [(String, a)]'
(All instance types must be of the form (T a1 ... an)
where a1 ... an are type variables,
and each type variable appears at most once in the instance head.
Use -XFlexibleInstances if you want to disable this.)
In the instance declaration for `JSON [(String, a)]'
Therefore, we recommend to add a footnote to the sentence above the code
sample.
You have to add the FlexibleInstances language extension.
|
Nellie McKesson |
May 24, 2011 |
Printed |
Page 153
code sample of ch06 |
This code also needs FlexibleInstances language extension.
? file: ch06/Overlap.hs
class Borked a where
bork :: a -> String
should be
? file: ch06/Overlap.hs
{}
class Borked a where
bork :: a -> String
|
Nellie McKesson |
May 24, 2011 |
Printed |
Page 159
2nd code example |
? file: ch06/JSONClassExport.hs
should be:
? file: ch06/JSONClass.hs
|
Nellie McKesson |
May 24, 2011 |
Printed |
Page 159
2nd code example in sidebar |
? file: ch06/JSONClassExport.hs
should be
? file: ch06/JSONClass.hs
|
Nellie McKesson |
May 24, 2011 |
Printed |
Page 160
Penultimate paragraph |
Taking this and wrapping it to become a JAry JValue is just a matter of
applying the newtype?s type constructor:
should be
Taking this and wrapping it to become a JAry JValue is just a matter of
applying the newtype?s data constructor:
|
Nellie McKesson |
May 24, 2011 |
Printed |
Page 160
Last paragraph |
To turn this into a JValue, we apply another type constructor:
should be
To turn this into a JValue, we apply another data constructor:
|
Nellie McKesson |
May 24, 2011 |
Printed |
Page 175/176
example |
While trying one of the examples I found an error due to a change in GHC. The example on pages 175/176 uses System.IO.Error.catch which has been replaced by System.IO.Error.catchIOError.
|
Anonymous |
Jun 09, 2014 |
Printed |
Page 179
1st paragraph 3rd line |
It's a pure function since it has no side effects
and always returns the same result each time it is called.
should be
It's a pure function since it has no side effects
and always returns the same result each time it is called
with the same string.
|
Nellie McKesson |
May 24, 2011 |
Printed |
Page 199
8th sample |
This is only an addendum to errata already confirmed.
8th sample might be written as follows:
ghci> getAllTextMatches("I, B. Ionsonii, uurit a lift'd batch" =~ "(uu|ii)":: (AllTextMatches [] String))
["ii","uu"]
Really verbose, isn't it?
|
Juan Antonio Zaratiegui Vallecillo |
May 12, 2010 |
Printed |
Page 203
First line after code block |
The line says "Our first clause stipulates that if we hit the end of the glob pattern (...) we return $".
It is not true that the first clause of globToRegex' stipulates that. It is a consequence of globToRegex on page 202, which calls globToRegex'. Although it is clear what you mean, the sentence needs to be reformulated.
|
Jan van Mansum |
Feb 14, 2010 |
Printed |
Page 213
bottom of page, example ch09/RecursiveContents.hs |
if you try to run this example on a Windows PC, using backslashes in the directory ['\'] name it will be interpreted as an escape character...see following:
getRecursiveContents "C:\Users\User\Downloads\rwh-examples2\examples\ch09"
gives the following error message:
<interactive>:1:25:
lexical error in string/character literal at character 'U'
if run with forward slash, it works, see following:
getDirectoryContents "C:/Users/User/Downloads/rwh-examples2/examples/ch09"
["Style.hs","SimpleFinder.hs","simplefinder.ghci","RecursiveContents.hs","recursivecontents.ghci","FoldDir.hs","flipMap.ghci","ControlledVisit.hs","BetterPredicate
.hs","betterpredicate.ghci","..","."]
*RecursiveContents>
actually, all Haskell commands fail with the backward slash...
|
patrick lynch |
Jan 25, 2011 |
Printed |
Page 214
2nd paragraph last sentence |
it wraps a value with the monad's type constructor.
should be
it wraps a value into monad's type.
|
Nellie McKesson |
May 24, 2011 |
PDF |
Page 216
4th paragraph |
It says
"This means that our attempt to use simpleFind will list directories ending in .c as well as files with the same extension."
But even if you apply (\p -> True)to list all the files, the result of simpleFind actually doesn't contain any directory names. Because for the directory part, it will only recursively list it.
|
Yi-Fan |
Apr 09, 2009 |
Printed |
Page 224
last code block |
? file: ch09/BetterPredicate.hs
constP :: a -> InfoP a
constP k _ _ _ _ = k
liftP' q f k w x y z = f w x y z `q` constP k w x y z
should be
? file: ch09/BetterPredicate.hs
constP :: a -> InfoP a
constP k _ _ _ _ = k
liftP' q f k = lift2 q f (constP k)
|
Nellie McKesson |
May 24, 2011 |
Printed |
Page 230
second codeblock defining foldTree |
The line
let path' = path </> name
in the definition of walk does not append the correct path when traversing down a subdirectory due to the fact that "path" actually holds the value submitted to foldTree.
path should actually be subpath (from the scope of the fold-function).
A quick fix would be:
foldTree ...
where
fold ...
where
walk ...
let path' = subpath </> name
|
Anonymous |
Oct 03, 2009 |
Printed |
Page 238
8th line from bottom |
There is an extra closed parenthesis.
... will be evaluated form left to right, as (a >>? b) >>? c).
should be
... will be evaluated form left to right, as (a >>? b) >>? c.
|
Nellie McKesson |
May 24, 2011 |
Printed |
Page 244
1st para of running text |
"(==>) lets us chain two Parse values together". From the type signature, it looks as the second is not a Parse value (Parse a) but a function yielding a Parse value (a -> Parse b).
|
david.m.carter |
May 10, 2009 |
Printed |
Page 246
11th line from bottom |
This says that we can only put a type a into a Foo if a is a member of
the Eq typeclass.
should be
This says that we can only put a type a into a Bar if a is a member of
the Eq typeclass.
|
Nellie McKesson |
May 24, 2011 |
Printed |
Page 247
2nd paragraph in "Constraints on Type..." |
(i.e., every element is bigger than the element below it),
should be
(i.e., every element is bigger than the element above it),
|
Nellie McKesson |
May 24, 2011 |
Printed |
Page 253
Beginning of running text |
"The (==>&) combinator chains parsers such as (==>), but the righthand side..."
This suggests (==>) is a parser, but it's a combinator. Also "righthand" should be two words. I think this wording is better:
"Like (==>), the (==>&) combinator chains parsers, but unlike (==>), the right hand side..."
|
david.m.carter |
May 10, 2009 |
Printed |
Page 266
1st paragraph (or page before) |
When talking about HPC, it mentions running "ghc -fhpc Run.hs --make", which works correctly, unless you've compiled the other modules without -fhpc first. A note should be added telling to user to delete all .hi and .o files in the directory. (When these steps are not taken, results like the following are found:
100% expressions used (0/0)
100% boolean coverage (0/0)
100% guards (0/0)
100% 'if' conditions (0/0)
100% qualifiers (0/0)
100% alternatives used (0/0)
100% local declarations used (0/0)
100% top-level declarations used (0/0)
)
|
Alex Mason |
Jan 04, 2009 |
PDF, Other Digital Version |
Page 266
Figure 11-1 |
Legends of Figures 11-1 and 11-3 (p.268) have been interchanged:
"Figure 11-1. Revised coverage for module Prettify2: 52% [...]"
"Figure 11-3. Coverage for module Prettify2: 42% [...]"
|
BlaF |
May 22, 2011 |
PDF |
Page 270
1st code sample |
checkDigit ds = 10 - (sum products `mod` 10)
should be
checkDigit ds = (10 - sum products `mod` 10) `mod` 10
Original checkDigit function cause Exception(Error in array index).
|
kariya_mitsuru |
Feb 11, 2010 |
Printed |
Page 273
last function defn on page |
It looks to me as if this definition of foldA1 will use the first element of "a" twice -- once as the seed ("a ! fst (bounds a)") and once when foldA accesses it as the first member of its copy of a.
|
david.m.carter |
May 10, 2009 |
PDF |
Page 275
1st code sample |
where (left, right) = splitAt 5 rest
should be
where (left, right) = splitAt 6 rest
|
kariya_mitsuru |
Feb 11, 2010 |
PDF |
Page 285
1st paragraph |
These two aren't the same as you stated as "evaluated in depth first order."
zip [distance d (scaleToOne ps) | d <- srl] digits
[(distance d (scaleToOne ps), n) | d <- srl, n <- digits]
|
Yi-Fan |
Apr 13, 2009 |
Printed |
Page 285
line of code just above "Remembering a Match's Parity" |
Surely this list comprehension is going to give you a cross product, not a zip? i.e. of srl and digits both have N elements, the first two expressions on the page will give a list of N pairs, but the third will give a list of N^2 pairs.
|
david.m.carter |
May 10, 2009 |
PDF |
Page 295
2nd code sample |
buildMap = M.mapKeys (10 -)
should be
buildMap = M.mapKeys (\c -> (10 - c) `mod` 10)
Original buildMap function build map that has key 10, not key 0.
|
kariya_mitsuru |
Feb 15, 2010 |
Printed |
Page 328
9th line from bottom |
... are its type constructor Maybe a, our ...
should be
... are its type constructor Maybe, our ...
|
Nellie McKesson |
May 24, 2011 |
Printed |
Page 336
Putting a Few Misconceptions to Rest |
There is no explanation for "Monads are for controlling the order of evaluation" while other items have.
|
Kazu Yamamoto |
Dec 16, 2008 |
Printed |
Page 336
6th paragraph |
For the assertion "Monads are for controlling the order of evaluation" no retort is given.
|
Frans Slothouber |
Feb 14, 2009 |
Printed |
Page 344
bottom |
The example of desugared binding with <- seems to have duplicated text. Specifically, the text
let f pattern = do act2
appears twice, at two levels of indentation. I believe the second appearance is either partially or entirely incorrect.
|
Chip Salzenberg |
Jan 20, 2009 |
Printed |
Page 347
4th paragraph in "Almost a State..." |
.. , and yet here we have a type with two parameters. The key is to
understand that we can partially apply a type just as ...
should be:
.. , and yet here we have a type constructor with two parameters. The
key is to understand that we can partially apply a type constructor just
as ...
|
Nellie McKesson |
May 24, 2011 |
PDF |
Page 348
3rd code sample |
-> (s -> (b, s)) -- (makeStep result) newState
should be
-> (s -> (b, s)) -- makeStep result
|
kariya_mitsuru |
Feb 17, 2010 |
Printed |
Page 348
2nd paragraph |
When we evaluate this, ... new function of type s -> (a, s)
should be
When we evaluate this, ... new function of type s -> (b, s)
|
Nellie McKesson |
May 24, 2011 |
Printed |
Page 359
First paragraph header |
"Golfing Practice: Association Lists"
On page 19 you talk about "duck typing" from Ruby; i.e. you mention a term and define it.
Now you introduce "Golfing" and it is not clear what that has to do with url encoding, alists, or monads. What is "golfing practice" anyway?
On page 369 in the book you have "Another Round of Golf" ... and that does not help to make it clear at all! It's like you are throwing purposefully cryptic headers at the reader.
|
Rodney S |
Jul 21, 2009 |
PDF |
Page 361
5th and 6th paragraph |
The type of "liftM MovieReview" is not
Maybe (String -> (String -> (String -> MovieReview)))
but
Maybe (String -> Maybe (String -> (String -> MovieReview)))
The result after applying "ap" on the result is not
Maybe (String -> (String -> MovieReview)))
but
Maybe (String -> Maybe (String -> MovieReview)))
|
ulrivo |
Apr 06, 2009 |
Printed |
Page 364
in "Rules for working with MonadPlus" |
The second rule is given as
-- file: ch15/MonadPlus.hs
v >> == mzero
however, it should be
v >> mzero == mzero
|
David Fries |
Mar 04, 2009 |
Printed |
Page 369
top of page |
The example runs "(fst . runSupply next) `fmap` randomsIO" twice to demonstrate that different random numbers are supplied each time. Instead, though, it gives on both invocations an error about 'next' being ambiguous, either from Supply or from System.Random. This contradicts the given code which explicitly hides the one from System.Random, so only the one from Supply should be visible.
|
HairyDude |
Jan 07, 2009 |
Printed |
Page 369
top |
Code example doesn't run ... error output printed in book but text implies that there was no problem.
|
douglashendricks |
Jan 28, 2012 |
Printed |
Page 422
top (first) code excerpt beginning with "$ ghci Regex.hs -lpcre" |
The terminal commands for ghci will not work with either the code given up to this point in the chapter or with your sample code from "Examples" on the O'Reilly site for "Real World Haskell". There are numerous omissions and errors. Below is a repaired version of your example Regex.hsc that works with the code excerpt.
{-- snippet headers --}
{-# LANGUAGE CPP, ForeignFunctionInterface #-}
module Regex where
import Foreign
import Foreign.C.Types
import Foreign.C.String
import System.IO.Unsafe
import qualified Data.ByteString.Char8 as DBC
#include <pcre.h>
{-- /snippet headers --}
{-- snippet newtype --}
-- | A type for PCRE compile-time options. These are newtyped CInts,
-- which can be bitwise-or'd together, using '(Data.Bits..|.)'
--
newtype PCREOption = PCREOption { unPCREOption :: CInt }
deriving (Eq,Ord,Show,Read)
{-- /snippet newtype --}
{-- snippet constants --}
-- PCRE compile options
#{enum PCREOption, PCREOption
, caseless = PCRE_CASELESS
, dollar_endonly = PCRE_DOLLAR_ENDONLY
, dotall = PCRE_DOTALL
, dupnames = PCRE_DUPNAMES
, extended = PCRE_EXTENDED
, extra = PCRE_EXTRA
, firstline = PCRE_FIRSTLINE
, multiline = PCRE_MULTILINE
, newline_cr = PCRE_NEWLINE_CR
, newline_crlf = PCRE_NEWLINE_CRLF
, newline_lf = PCRE_NEWLINE_LF
, no_auto_capture = PCRE_NO_AUTO_CAPTURE
, ungreedy = PCRE_UNGREEDY
}
{-- /snippet constants --}
{-- snippet combine --}
-- | Combine a list of options into a single option, using bitwise (.|.)
combineOptions :: [PCREOption] -> PCREOption
combineOptions = PCREOption . foldr ((.|.) . unPCREOption) 0
{-- /snippet combine --}
{-- snippet data --}
data Regex = Regex !(ForeignPtr PCRE)
!DBC.ByteString
deriving (Eq, Ord, Show)
{-- /snippet data --}
{-- snippet unit --}
type PCRE = ()
--The "type PCRE = PCRE (Ptr PCRE)" trick on p.416 is rejected by ghci
{-- /snippet unit --}
{-- snippet pcre_compile --}
foreign import ccall unsafe "pcre.h pcre_compile"
c_pcre_compile :: CString
-> PCREOption
-> Ptr CString
-> Ptr CInt
-> Ptr Word8
-> IO (Ptr PCRE)
{-- /snippet pcre_compile --}
{- snippet compile -}
compile :: DBC.ByteString -> [PCREOption] -> Either String Regex
compile str flags = unsafePerformIO $
DBC.useAsCString str $ \pattern -> do
alloca $ \errptr -> do
alloca $ \erroffset -> do
pcre_ptr <- c_pcre_compile pattern (combineOptions flags) errptr
erroffset nullPtr
if pcre_ptr == nullPtr
then do
err <- peekCString =<< peek errptr
return (Left err)
else do
reg <- newForeignPtr finalizerFree pcre_ptr --release w/ free()
return (Right (Regex reg str))
{- end snippet compile -}
|
Barney Kendrick |
Feb 24, 2009 |
Printed |
Page 426
two ghci examples |
The "match" executions in the two examples take unnecessary "[]" in the end. For instance,
match r (pack "the quick brown fox") []
should be
match r (pack "the quick brown fox")
There are 5 errors of this in page 426.
Note "RegexFull.hsc" in the online examples should be used instead of "Regex.hsc".
|
Kazu Yamamoto |
May 10, 2009 |
Printed |
Page 433
towards the bottom of the page |
In the section about the ordering of Monad transformers:
"Our transformer stack has IO on the bottom, then StateT, with ReaderT on top. In this particular case, it doesn't matter whether we have ReaderT or WriterT on top, but IO must be on the bottom."
I think WriterT should rather be StateT. WriterT is never used in the following examples.
|
David Fries |
Mar 04, 2009 |
Printed |
Page 433
towards the bottom of the page |
In the section about the ordering of Monad transformers:
"Our transformer stack has IO on the bottom, then StateT, with ReaderT on top. In this particular case, it doesn't matter whether we have ReaderT or WriterT on top, but IO must be on the bottom."
I think WriterT should rather be StateT. WriterT is never used in the following examples.
|
David Fries |
Mar 04, 2009 |
Printed |
Page 436
Top box |
In the exercises at the top of page 436 it should be StateT instead of WriterT
|
Anonymous |
Jun 09, 2014 |
Printed |
Page 472
2nd bullet point. |
The typeclasses Enum and bounded are mentioned and we're told to refer ``to "Important Built-in Typeclasses" on page 139'' for more information. However, the section starting on pg 139 doesn't tell us anything about Enum or Bounded (except for briefly mentioning minBound and maxBound in a table). I think those typeclasses are supposed to be explained though, because of pg 472 and because the section following "Important Built-in Typeclasses" starts by mentioning Enum and Bounded among the typeclasses that standard Haskell compilers can automatically derive (pg 148).
|
enoksrd |
Feb 06, 2009 |
Printed |
Page 495
2nd paragraph, ghci example |
I had a great deal of trouble in loading Sqlite3 into my Windows Vista PC - I honestly don't know what version was finally loaded...
I couldn't get the following command to work - it complained that it couldn't find the database "test1.db":
conn <- connectSqlite3 "test1.db"
In desparation I finally created an empty file with this name and tried the command and it worked...
However, when I went on to page 496 in an attempt to create a table using the following command, it complained that the database could not be found:
run conn "CREATE TABLE test (id INTEGER NOT NULL, desc VARCHAR(80))" []
With this installation of Sqlite3, I cannot run it from the command line so, therefore, I'm unable to create a database from the command line, bummer...
I then went on to Chapter 22 and ran into a load problem ...
I'm so confused...I know this is 'open source' software, but should it be this difficult?
|
patrick lynch |
Feb 02, 2011 |
Printed |
Page 495
2nd paragraph, ghci example |
I had a great deal of trouble in loading Sqlite3 into my Windows Vista PC - I honestly don't know what version was finally loaded...
I couldn't get the following command to work - it complained that it couldn't find the database "test1.db":
conn <- connectSqlite3 "test1.db"
In desparation I finally created an empty file with this name and tried the command and it worked...
However, when I went on to page 496 in an attempt to create a table using the following command, it complained that the database could not be found:
run conn "CREATE TABLE test (id INTEGER NOT NULL, desc VARCHAR(80))" []
With this installation of Sqlite3, I cannot run it from the command line so, therefore, I'm unable to create a database from the command line, bummer...
I then went on to Chapter 22 and ran into a load problem ...
I'm so confused...I know this is 'open source' software, but should it be this difficult?
|
patrick lynch |
Feb 02, 2011 |
Printed |
Page 497
...in the ghci example at the bottom of the page |
first i had to change the first statement from:
ghci> conn <- connectSqlite3 "test1.db"
to [since I'm running a Windows Vista PC]:
ghci> conn <- connectSqlite3 "/users/user/test1.db"
then when i execute the following command:
run conn "INSERT INTO test VALUES (?, ?)" [toSql 0, toSql "zero"]
the following error message is returned:
<interactive>:1:43:
No instance for (Data.Convertible.Base.Convertible t SqlValue)
arising from a use of `toSql' at <interactive>:1:43-49
Possible fix:
add an instance declaration for
(Data.Convertible.Base.Convertible t SqlValue)
In the expression: toSql 0
In the third argument of `run', namely `[toSql 0, toSql "zero"]'
In the expression:
run conn "INSERT INTO test VALUES (?, ?)" [toSql 0, toSql "zero"]
|
patrick lynch |
Feb 03, 2011 |
Printed |
Page 517
|
I tried to download gtk2hs onto a Windows Vista PC using the link shown in the book, namely: http://www.haskell.org/gtk2hs/download/.
FYI: this link has been changed to: http://www.haskell.org/haskellwiki/Gtk2Hs.
Unfortunately, even with the assistance of the beginners@haskell.org I was unable to do so...If you know of another way of installing gtk2hs, please let me know.
Thank you
|
patrick lynch |
Feb 06, 2011 |
Printed |
Page 536
1st sentence of 1st paragraph of 'Safe Resource Management: A Good Idea, and Easy Besides' |
"We can THE take the pattern ..." - should "THE" it be "then" of omitted entirely?
|
Pierre Caillaud |
May 12, 2016 |
Printed |
Page 548
|
The force function defined on page 547 does not force the evaluation of the elements in the list it takes. It only evaluates the spine of the list. This can be verified using GHCI as follows:
xs = let ys = [undefined,undefined,undefined]
in force ys `seq` ys
*Main> length xs
3
Hence, evaluating its length can't be used to force the evaluation of random numbers in the input list before the sorting procedure.
The right function to use here in order to avoid the problems described on page 548 is forceList (defined on page 552 of the book).
|
Pepe Gallardo |
Mar 30, 2009 |
Printed |
Page 549
3rd paragraph |
In order to force the sort to take place, you suggest evaluating the length of the sorted list. That works for the sort functions that you use, but is not a general solution. For instance, calculating the length of a list sorted using the following function does not evaluate its elements:
import List
sort' :: (Ord a) => [a] -> [a]
sort' xs = [ select i xs | i <- [0..length xs-1] ]
where
select 0 xs = minimum xs
select (n+1) xs = select n (delete (select 0 xs) xs)
*Main> sort' [10,9..1]
[1,2,3,4,5,6,7,8,9,10]
*Main> length (sort' [undefined,undefined])
2
I must admit that this is a very inefficient and imperative sort function, but my point is show that the proposed solution is not general enough. Wouldn't it be better to use force as you already do in the generation of the initial list?
|
Pepe Gallardo |
Mar 26, 2009 |
Printed |
Page 598
2nd para from bottom |
"We include -fvia-C here mainly to show how to compile using this option:" (cabal code here....)
The problem is the "cabal code" does not mention "-fvia-C" at all. Perhaps if the line ended in a "." instead of a ":", the one could interpret the line meaning "the above paragraph mentions -fvia-C for completeness." But the ":" drives one to look at the next text and then not finding "-fvia-C" is confusing.
|
Rodney S |
Aug 03, 2009 |
PDF |
Page 625
6th paragraph |
The function removeInv doesn't remove an item from a list.
The following similar function does it:
removeInv :: Eq a => a -> [a] -> Maybe [a]
removeInv x xs =
case span (/= x) xs of
(zs,(_:ys)) -> Just $ zs++ys
(_,[]) -> Nothing
|
ulrivo |
Jul 18, 2009 |
Printed |
Page 628
last para under "Choosing Between Alternatives" header |
the sentence:
"If sellItem fail, orelse will invoke the return False action, causing our sale function to return immediately."
You give the orElse type signature, but no use of it and no "return False" application or even a "sellItem" application for that matter. I think you are missing something like this:
sellItem Banjo 42 steveMartin slimPickens `orElse` return False
otherwise the assertion "will invoke the return False action" does not make sense. What "return False" action?
|
Rodney S |
Aug 05, 2009 |