Errata: June 24, 2018
Thank you for purchasing Get Programming with Haskell. Please post any errors, other than those listed below, in the book's Author Online Forum. We'll compile a comprehensive list and publish it here for everyone's convenience.
These errors occur in the book's first printing. Unless noted, these corrections have been made to the electronic versions.

Page ix:

In the acknowledgements, Vitaly Bragilevski's name is misspelled in one instance.

Page 15:

GHCi>simple^2

should be:

GHCI>simple 3

Page 4, electronic and print:

helloworld is misspelled. Re;lace code with the following:

$ghc hello.hs -o helloworld
[1 of 1] Compiling Main
Linking helloworld ....

Page 31:

Aside from their role as a theoretical corner store of functional programming, they provide practical benefits.

should be:

Aside from their role as a theoretical cornerstone of functional programming, they provide practical benefits.

Page 34, print and electronic:

In the second and last paragraph, change ifEveninc to ifEvenInc.

Page 76, lesson 8:

There is a function with the following definition right before listing 8.1:

myLength xs = 1 + length (tail xs)

The definition should be:

myLength xs = 1 + myLength (tail xs)

(This is correct in listing 8.1.)

Page 87, print and electronic:

Delete the second passed in the following sentence: The difference is that the function passed to `filter` must be passed a function that returns True or False. It should be: The difference is that the function passed to `filter` must be a function that returns True or False.

Page 153, lesson 14:

In the sidebar, "Creating types with newtype" the following sentence:

"Any type that you can define with newtype, you can also define using data.

The word "data" should be: in code font. This is also true of the last sentence:

"For simplicity, we'll stick to creating types with data throughout this book."

Page 157, print and electronic:

Replace listing 15.2 with the following:

rotN :: (Bounded a, Enum a) => Int -> a -> a
rotN alphabetSize c = toEnum rotation
    where halfAlphabet = alphabetSize `div` 2
        offset = fromEnum c + halfAlphabet
        rotation = offset `mod` alphabetSize

Page 158, lesson 15:

In listing 15.5

[FourLetterAlpha]

should be:

[FourLetterAlphabet]

Page 169, print and electronic:

rotEncoder function is misspelled.

This allows you to create a common interface for any new ciphers you may write, as well as making working with rotEncode and applyOTP easier.

should be:

This allows you to create a common interface for any new ciphers you may write, as well as making working with rotEncoder and applyOTP easier. In this example, you can use two type constructors that can either be a Name consisting of two Strings or a NameWithMiddle consisting of three Strings.

Page 177, print and electronic:

The Book data type in listing 16.2 isn't a correct translation.

data Book = Author String String Int 

should be:

data Book = Book AuthorName String String Int Double 

Page 181, print and electronic:

In this example, you can use two type constructors that can either be a FirstName consisting of two Strings or a NameWithMiddle consisting of three Strings.

should be:

In this example, you can use two type constructors that can either be a Name consisting of two Strings or a NameWithMiddle consisting of three Strings.

Page 188, lesson 17:

This is arguably not really an error, but technically, in Consider this:

"this" ++ " " ++ "is" ++ " " ++ "a" ++ " " ++ "bit" ++ "much"

should be:

"this" ++ " " ++ "is" ++ " " ++ "a" ++ " " ++ "bit" ++ " " ++ "much"

Page 194, lesson 17:

Some missing back ticks snuck through here, as well as missing >s after the GHCi. After listing 17.7 we see the following code:

GHCi [1,2,3] ++ []
[1,2,3]
				
GHCi [1,2,3] <> []
[1,2,3]
				
GHCi [1,2,3]  mappend  mempty
[1,2,3]
The correct code follows:

GHCi> [1,2,3] ++ []
[1,2,3]
				
GHCi> [1,2,3] <> []
[1,2,3]
				
GHCi> [1,2,3]  `mappend`  mempty
[1,2,3]

Page 208, print and electronic:

But they'll come up as you dive deeper into the more advanced types classes covered in unit 5 (Functor, Applicative, and Monad).

should be:

But they'll come up as you dive deeper into the more advanced type classes covered in unit 5 (Functor, Applicative, and Monad).

Page 209, print and electronic:

In GHCi, you use the :kind command to look up the kinds of any types you're unsure of (make sure to import Data.Map):

should be:

In GHCi, you use the :kind command to look up the kinds of any types you're unsure of (make sure to import Data.Map using a qualified import, see section 18.2.3):

Page 209, lesson 18:

The following code:

GHCi> :kind Map.Map Map.Map :: * -> * -> *

should be: on separate lines as follows:

GHCi> :kind Map.Map 
Map.Map :: * -> * -> *

Page 209, print and electronic:

The answer should be:

(,,) :: * -> * -> * -> *

Page 224, print and electronic:

Maybe is a great example of how powerful types make your code less erro- prone.

should be:

Maybe is a great example of how powerful types make your code less error-prone."

Page 278, print and electronic:

Create your own version of T.lines and T.unlines by using splitOn and T.intercalate.

should be:

Create your own version of T.lines and T.unlines by using T.splitOn and T.intercalate.

Page 288, print and electronic:

You can see that this code never closes the file handle, and just returns the results of hGetContent.

should be:

You can see that this code never closes the file handle, and just returns the results of hGetContents.

Page 319, print and electronic:

Listing 26.19 title references wrong type.

MarcDirectoryRaw type synonym and dirEntryLength

should be:

MarcDirectoryEntryRaw type synonym and dirEntryLength

Page 340, lesson 27:

There's a missing space after the CHCi> prompt at the end of the page. The following:

GHCi>Map.lookup 1 htmlPartsDB
should be:

GHCi> Map.lookup 1 htmlPartsDB	

Page 342, print and electronic:

Q27.1 When we introduced parameterized types in lesson 15, you used a minimal type Box as the example:

should be:

Q27.1 When we introduced parameterized types in lesson 18, you used a minimal type Box as the example:

Page 348, print and electronic:

In lesson 5, you learned that partial application means that calling a function with fewer functions that it requires results in a function waiting for the remaining arguments.

should be:

In lesson 5, you learned that partial application means that calling a function with fewer arguments that it requires results in a function waiting for the remaining arguments.

Then in section 10.2.2, you saw that all functions are functions of one argument.

should be:

Then in section 11.2.2, you saw that all functions are functions of one argument.

Page 368, lesson 29:

The commas in listing 29.10 should be aligned with the opening bracked ([) as in the other listings on this page.

Page 389, print and electronic:

Figure 31.1 on the right side.

putStrLn nameStatement

should be:

putStrLn (nameStatement name)

Page 412, print and electronic:

Because you want to see how well you can treat lists such as tables in a relational database, you'll use an example involving students, teachers, courses, and enrollments.

should be:

Because you want to see how well you can treat lists like tables in a relational database, you'll use an example involving students, teachers, courses, and enrollments.

Page 413, print and electronics:

Sophomore is misspelled in Listing 33.4

,(Student 5 Sophmore (Name "Jean" "Baudrillard"))

should be:

,(Student 5 Sophomore (Name "Jean" "Baudrillard"))

Pages 472, 474, 476, 477, and 478, print and electronic:

Change all instances of check the length of primes to getting the last prime.

| n >= length primes = Nothing 

should be:

| n >= last primes = Nothing 

For the property tests:

val >= length primes 

should be:

val >= last primes 

Page 425, print and electronic:

Listing 33.23 is missing a closing parenthesis in line 3:

(studentName st, course en))

should be:

(studentName st, course en)))

Page 480, print and electronic:

The command line misspells exec.

$ stack exe primes-exe 

should be:

$ stack exec primes-exe 

Page 485, print and electronic:

Instances of headaches.cabal should be palindrome-checker.cabal.

As a refresher from lesson 35, open the headaches.cabal file in the projects root directory, find the executable section of the .cabal file, and append -Wall to the list of ghc- options as shown here:

executable headaches-exe 
hs-source-dirs: app 
main-is: Main.hs 
ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall 
build-depends: base 
, headaches 
default-language: Haskell2010

should be:

As a refresher from lesson 35, open the palindrome-checker.cabal file in the projects root directory, find the executable section of the .cabal file, and append -Wall to the list of ghc- options as shown here:

executable palindrome-checker-exe 
hs-source-dirs: app 
main-is: Main.hs 
ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall 
build-depends: base 
, text 
, palindrome-checker 
default-language: Haskell2010

Page 583, print and electronic:

In Q31.1, remove the colon character at the end of line 17.

putStrLn (describePizza betterPizza):

should be:

putStrLn (describePizza betterPizza)