List of Listings

Lesson 1. Getting started with Haskell

Listing 1.1. hello.hs a Hello World program

Listing 1.2. A messy version of first_prog.hs

Listing 1.3. Corrected toPart function

Listing 1.4. Defining the bodyPart and fromPart functions

Listing 1.5. Defining the createEmail function

Listing 1.6. Improved first_prog.hs with a cleaned-up main

Lesson 2. Functions and functional programming

Listing 2.1. Hidden state in function calls

Listing 2.2. Confusing behavior in standard libraries

Listing 2.3. Defining your first variable

Listing 2.4. Variables aren’t variable!

Listing 2.5. calcChange v.1

Listing 2.6. calcChange v.2

Lesson 3. Lambda functions and lexical scope

Listing 3.1. sumSquareOrSquareSum v.1

Listing 3.2. The overwrite function

Lesson 4. First-class functions

Listing 4.1. ifEvenInc

Listing 4.2. ifEvenDouble and ifEvenSquare

Listing 4.3. ifEven

Listing 4.4. names

Listing 4.5. compareLastNames

Listing 4.6. addressLetter v.1

Listing 4.7. sfOffice, nyOffice, renoOffice

Listing 4.8. getLocationFunction

Listing 4.9. addressLetter v.2

Lesson 5. Closures and partial application

Listing 5.1. ifEvenInc, ifEvenDouble, ifEvenSquare

Listing 5.2. getRequestUrl

Listing 5.3. exampleUrlBuilder v.1

Listing 5.4. genApiRequestBuilder

Listing 5.5. myExampleUrlBuilder v.1

Listing 5.6. exampleUrlBuilder v.2 and myExampleUrlBuilder v.2

Listing 5.7. addressLetterV2

Lesson 6. Lists

Listing 6.1. Consing characters and strings

Listing 6.2. isPalindrome

Listing 6.3. respond

Listing 6.4. takeLast

Listing 6.5. ones

Listing 6.6. assignToGroups

Lesson 7. Rules for recursion and pattern matching

Listing 7.1. myGCD

Listing 7.2. sayAmount v.1

Listing 7.3. sayAmount v.2

Listing 7.4. myHead

Lesson 8. Writing recursive functions

Listing 8.1. myLength

Listing 8.2. myTake

Listing 8.3. myCycle

Listing 8.4. collatz

Lesson 9. Higher-order functions

Listing 9.1. JavaScript map example

Listing 9.2. myMap

Listing 9.3. myFilter

Listing 9.4. myReverse

Listing 9.5. myFoldl

Listing 9.6. myFoldr

Lesson 10. Capstone: Functional object-oriented programming with robots!

Listing 10.1. Constructor for a basic cup object

Listing 10.2. coffeeCup

Listing 10.3. getOz message

Listing 10.4. Defining a drink message that updates state

Listing 10.5. Improving the drink definition

Listing 10.6. Defining isEmpty

Listing 10.7. Using foldl to model taking many sips

Listing 10.8. A robot constructor

Listing 10.9. name, attack, and hp helper functions

Listing 10.10. getName, getAttack, and getHP accessors

Listing 10.11. setName, setAttack, and setHP accessors

Listing 10.12. Defining a printRobot message

Listing 10.13. Completing the damage function

Listing 10.14. The definition of fight

Listing 10.15. Three-round robot fight with simultaneous attacks

Listing 10.16. Changing the priority of attacks

Listing 10.17. Order has no importance in execution of Haskell code

Lesson 11. Type basics

Listing 11.1. Integer type

Listing 11.2. Common types Char, Double, and Bool

Listing 11.3. List types

Listing 11.4. Tuple types

Listing 11.5. Converting from one type to another with half

Listing 11.6. Example of reading values from strings: anotherNumber

Listing 11.7. Type signatures for first-class functions: ifEven

Listing 11.8. simpleInt and

Listing 11.9. Using type variables: simple

Listing 11.10. Multiple type variables: makeTriple

Lesson 12. Creating your own types

Listing 12.1. Defining the patientInfo function

Listing 12.2. Type synonyms: FirstName, LastName, Age, and Height

Listing 12.3. Type synonym: PatientName

Listing 12.4. Accessing PatientName values: firstName and lastName

Listing 12.5. Defining the sexInitial function

Listing 12.6. Defining the type RhType

Listing 12.7. Defining the type ABOType

Listing 12.8. Displaying your types: showRh, showABO, showBloodType

Listing 12.9. Defining the canDonateTo function

Listing 12.10. Support different names: MiddleName and Name

Listing 12.11. Displaying multiple constructors: showName

Listing 12.12. Patient v.1

Listing 12.13. getName, getAge, getBloodType

Listing 12.14. Patient v.2 (with record syntax)

Listing 12.15. Updating jackieSmith by using record syntax

Lesson 13. Type classes

Listing 13.1. Num type class definition

Listing 13.2. Using type classes: addThenDouble

Listing 13.3. Defining your own type class: Describable

Listing 13.4. Ord type class requires Eq type class

Listing 13.5. Eq type class generalizes the idea of equality

Listing 13.6. Bounded type class requires values but no functions

Listing 13.7. Show type class definition

Listing 13.8. Defining the Icecream type

Listing 13.9. The Icecream type deriving the Show type class

Lesson 14. Using type classes

Listing 14.1. Defining the SixSidedDie data type

Listing 14.2. The SixSidedDie type deriving Show

Listing 14.3. Creating an instance of Show for SixSidedDie

Listing 14.4. Incorrect attempt to implement show for SixSidedDie

Listing 14.5. Demonstrating the need for polymorphism defining show for TwoSidedDie

Listing 14.6. Implementing an instance of Eq for SixSidedDie

Listing 14.7. Partial definition of compare for SixSidedDie

Listing 14.8. How deriving Ord is determined

Listing 14.9. Implementing Enum for SixSidedDie (errors with implementation)

Listing 14.10. Using a type synonym for Name

Listing 14.11. Attempt to implement Ord for a type synonym

Listing 14.12. Defining a new type Name using data

Listing 14.13. Correct implementation of Ord for Name type

Lesson 15. Capstone: Secret messages!

Listing 15.1. Defining a four-letter alphabet

Listing 15.2. A generic rotN function to work on any alphabet

Listing 15.3. Getting the number representing the largest Char

Listing 15.4. Rotating a single Char

Listing 15.5. A message in your four-letter alphabet

Listing 15.6. Defining a fourLetterEncoder with map

Listing 15.7. A three-letter alphabet, message, and encoder

Listing 15.8. A rotNdecoder that works with odd-numbered alphabets

Listing 15.9. A working decoder for ThreeLetterAlphabet

Listing 15.10. Rotating strings with rotEncoder and rotDecoder

Listing 15.11. xorBool, a foundation for xor

Listing 15.12. xorPair to xor pairs of Bools

Listing 15.13. Finally, your completed xor function

Listing 15.14. Bits type synonym

Listing 15.15. intToBits' starting to convert an Int type to Bits

Listing 15.16. maxBits and your final intToBits function

Listing 15.17. charToBits to convert Chars into Bits

Listing 15.18. bitsToInt to go backward from Bits to an Int type

Listing 15.19. Completing the transformation by going back from bitsToChar

Listing 15.20. A simple pad

Listing 15.21. Your plain text

Listing 15.22. applyOTP' for converting a string to bits with a one-time pad

Listing 15.23. Finally, applyOTP to encode strings using a one-time pad

Listing 15.24. Partial application to create an encoderDecoder

Listing 15.25. A Cipher class to generalize your cipher operations

Listing 15.26. The Rot data type

Listing 15.27. Making Rot an instance of Cipher

Listing 15.28. The OneTimePad data type

Listing 15.29. Making OneTimePad an instance of Cipher

Listing 15.30. Using lazy evaluation to create a limitless pad

Listing 15.31. A linear congruential PRNG

Listing 15.32. examplePRNG

Lesson 16. Creating types with “and” and “or”

Listing 16.1. C structs are product types—an example with a book and author

Listing 16.2. C’s author_name and book structs translated to Haskell

Listing 16.3. Using record syntax for Book to show the similarity to a C struct

Listing 16.4. A first pass at defining a Book class in Java

Listing 16.5. Expanding your selection by adding a Java class for VinylRecord

Listing 16.6. Creating a StoreItem superclass of Book and VinylRecord in Java

Listing 16.7. A CollectibleToy class in Java

Listing 16.8. A common sum type: Bool

Listing 16.9. Using a sum type to model names with and without middle names

Listing 16.10. A Creator type that’s either an Author or an Artist

Listing 16.11. Defining the Author type by using your existing Name type

Listing 16.12. An artist can be either a Person or a Band

Listing 16.13. Expanding your Name type to work with H.P. Lovecraft

Listing 16.14. Making a Creator type for H.P. Lovecraft

Listing 16.15. Easily expanding Name to work with Andrew W.K.

Listing 16.16. The Book type using Creator

Listing 16.17. The VinylRecord type

Listing 16.18. A StoreItem type is either a Book or a VinylRecord

Listing 16.19. Adding a CollectibleToy type

Listing 16.20. Easily refactoring StoreItem to include CollectibleToy

Listing 16.21. An example of using the StoreItem type with a price function

Lesson 17. Design by composition—Semigroups and Monoids

Listing 17.1. Examples of using function composition to create functions

Listing 17.2. Semigroup for Integer

Listing 17.3. Defining the Color type

Listing 17.4. Implementing Semigroup for Color v1

Listing 17.5. Reimplementing Semigroup for Color to support associativity

Listing 17.6. The rational definition of Monoid

Listing 17.7. The actual definition of Monoid

Listing 17.8. Type synonyms for Events and Probs

Listing 17.9. PTable data type

Listing 17.10. createPTable makes a PTable ensuring all probabilities sum to 1

Listing 17.11. showPair creates a String for a single event-probability pair

Listing 17.12. Making PTable an instance of Show

Listing 17.13. The cartCombine function for the Cartesian product of lists

Listing 17.14. combineEvents and combineProbs

Listing 17.15. Making PTable an instance of Semigroup

Listing 17.16. Making PTable an instance of Monoid

Listing 17.17. Example PTables coin and spinner

Lesson 18. Parameterized types

Listing 18.1. Defining the wrap and unwrap functions for Box

Listing 18.2. Defining the Triple type

Listing 18.3. Defining a 3D point in space as a Triple

Listing 18.4. Using a Triple to define a name data type

Listing 18.5. Using a Triple to define Initials

Listing 18.6. Assessors for the Triple type

Listing 18.7. Defining a toList function on Triple

Listing 18.8. A function to transform Triples

Listing 18.9. Defining your own list

Listing 18.10. Comparing your List to the built-in list

Listing 18.11. Defining ourMap for your list

Listing 18.12. Definition of a tuple

Listing 18.13. Exploring the types of tuples

Listing 18.14. Creating an item inventory

Listing 18.15. The Organ data type

Listing 18.16. An example list of organs

Listing 18.17. A List of IDs to represent the locations of various organs

Listing 18.18. Pairs of organs and IDs v1

Listing 18.19. organPairs created using zip

Listing 18.20. Creating your organCatalog

Listing 18.21. The type signature for Map.lookup

Lesson 19. The Maybe type: dealing with missing values

Listing 19.1. Definition of Maybe

Listing 19.2. List of possibleDrawers in your organCatalog

Listing 19.3. Definition of getDrawers

Listing 19.4. A list of availableOrgans that can contain missing values

Listing 19.5. countOrgan function counts instances of an Organ

Listing 19.6. Definition of isSomething

Listing 19.7. Using isSomething with filter to clean [Maybe Organ]

Listing 19.8. Definition of showOrgan

Listing 19.9. Using showOrgan with map

Listing 19.10. Defining key functions and data types for mad scientist request

Listing 19.11. The core functions process and report

Listing 19.12. Ideal definition of processRequest (won’t compile)

Listing 19.13. processAndReport to handle the Maybe Organ data

Listing 19.14. processRequest with support for Maybe Organ

Lesson 20. Capstone: Time series

Listing 20.1. Imports for time_series.hs

Listing 20.2. Your data

Listing 20.3. The definition of the TS data type

Listing 20.4. createTS to make an easier interface for creating TS types

Listing 20.5. fileToTS to easily convert your file data into TS types

Listing 20.6. showTVPair to render time/value pairs readable

Listing 20.7. Making TS an instance of Show by using zipWith and showTVPair

Listing 20.8. Converting all your data files into TS types

Listing 20.9. insertMaybePair, a helper function for inserting (k, Maybe v) pairs

Listing 20.10. combineTS

Listing 20.11. Making TS an instance of Semigroup

Listing 20.12. Making TS an instance of Monoid

Listing 20.13. tsAll easily created using mconcat

Listing 20.14. mean to average a list of most number types

Listing 20.15. makeTSCompare and useful type synonyms

Listing 20.16. compareTS, a generic means of applying comparison functions to TS

Listing 20.17. Trivially creating minTS and maxTS using compareTS

Listing 20.18. Type signature of diffPair

Listing 20.19. Definition of diffPair

Listing 20.20. diffTS to take the diff of a TS

Listing 20.21. meanMaybe, which takes the mean of a list of Maybe a values

Listing 20.22. movingAvg calculates the moving average of a Maybe a list

Listing 20.23. maTS for calculating the moving average of a TS with centering

Lesson 21. Hello World!—introducing IO types

Listing 21.1. A simple Hello World program

Listing 21.2. roll.hs program for simulating the roll of a die

Listing 21.3. Understanding do-notation in your Hello World program

Listing 21.4. Calculating the area of a pizza given its diameter

Listing 21.5. Pizza type synonym

Listing 21.6. Calculating cost per inch

Listing 21.7. Comparing two pizzas

Listing 21.8. Describing a pizza

Listing 21.9. Putting all of your code together in main

Listing 21.10. costData Map containing pizza cost info

Listing 21.11. sizeData Map containing pizza size info

Listing 21.12. maybeMain: a version of your previous main using Maybe instead of IO

Lesson 22. Interacting with the command line and lazy I/O

Listing 22.1. Getting command-line arguments by using getArgs

Listing 22.2. Proposed solution to print your args (note: won’t compile)

Listing 22.3. Next improvement: using mapM (still won’t compile)

Listing 22.4. Using a command-line argument to determine how many lines to read

Listing 22.5. Reading a number of lines equal to the user’s argument

Listing 22.6. The full content of your sum.hs program

Listing 22.7. A simple main to explore lazy I/O

Listing 22.8. Sample data representing a string of input characters

Listing 22.9. Defining myLines with splitOn from Data.List.Split

Listing 22.10. toInts function to convert your Char list into a list of Ints

Listing 22.11. Your lazy solution to processing your numbers

Lesson 23. Working with text and Unicode

Listing 23.1. Converting back and forth between String and Text types

Listing 23.2. The problem with using literal strings to define Text

Listing 23.3. The same numeric literal used in three types

Listing 23.4. Using OverloadedStrings to easily assign Text using a literal

Listing 23.5. sampleInput of type Text

Listing 23.6. someText as a sample input for words

Listing 23.7. Code for splitOn example

Listing 23.8. A Unicode text variable for dharma written in Devanagari script

Listing 23.9. Your search text from the Bhavagad Gita

Listing 23.10. The highlight function for highlighting text segments

Listing 23.11. Full file for your program

Lesson 24. Working with files

Listing 24.1. hello.txt sample file

Listing 24.2. main, which opens and closes a file

Listing 24.3. Reading from a file and writing to stdout and another file

Listing 24.4. Checking whether helloFile is empty before printing the first line

Listing 24.5. Sample contents of stats.dat file for your fileCounts.hs program

Listing 24.6. getCounts collects character, word, and line count info into a tuple

Listing 24.7. countsText renders count data in a human-readable form

Listing 24.8. Putting your code together into main

Listing 24.9. Revised main with the readFile function expanded out

Listing 24.10. main with the evaluation bugs fixed

Lesson 25. Working with binary data

Listing 25.1. ByteString defined by using the OverloadedStrings extension

Listing 25.2. Trying to unpack a ByteString into a String causes an error

Listing 25.3. Basic layout for your glitcher.hs file

Listing 25.4. intToChar creates a valid byte from an Int

Listing 25.5. intToBC takes an Int and gives you a single-character ByteString

Listing 25.6. replaceByte removes a byte and replaces it with a new one

Listing 25.7. randomReplaceByte applies random numbers to replaceByte

Listing 25.8. sortSection sorts a section of bytes in your file

Listing 25.9. Randomizing your sortSection by using an IO action

Listing 25.10. Your main revised to use randomSortSection to glitch your file

Listing 25.11. A cumbersome approach to applying multiple actions

Listing 25.12. An improved way to use multiple actions with foldM

Listing 25.13. Creating a Unicode BC.ByteString

Listing 25.14. Same Unicode example, properly represented as Text

Listing 25.15. Attempting to transform Text into a ByteString

Listing 25.16. Converting between Text and ByteString with de/encodeUtf8

Lesson 26. Capstone: Processing binary files and book data

Listing 26.1. The necessary imports for marc_to_html.hs

Listing 26.2. Type synonyms for Author and Title

Listing 26.3. Create a Book type

Listing 26.4. Html type synonym

Listing 26.5. bookToHtml creates an individual snippet of HTML from a book

Listing 26.6. A collection of sample books

Listing 26.7. Turning a list of books into an HTML document with booksToHtml

Listing 26.8. Temporary main to write your books list to HTML

Listing 26.9. Type synonyms for MarcRecordRaw and MarcLeaderRaw

Listing 26.10. Declaring the length of the leader to be 24

Listing 26.11. getLeader grabs the first 24 bytes of the record

Listing 26.12. rawToInt and getRecordLength

Listing 26.13. nextAndRest breaks a stream of records into a head and tail

Listing 26.14. Converting a stream of raw data into a list of records

Listing 26.15. Type synonym for MarcDirectoryRaw

Listing 26.16. Getting the base address to determine the size of the directory

Listing 26.17. Calculating the length of the directory with getDirectoryLength

Listing 26.18. Putting everything together to getDirectory

Listing 26.19. MarcDirectoryRaw type synonym and dirEntryLength

Listing 26.20. splitDirectory breaks down the directory into its entries

Listing 26.21. FieldMetadata type

Listing 26.22. Converting a raw directory entry into a FieldMetadata type

Listing 26.23. Mapping makeFieldMetadata to [FieldMetadata]

Listing 26.24. Type synonym for FieldText

Listing 26.25. Getting the FieldText

Listing 26.26. Getting the field delimiter

Listing 26.27. Tags and subfield codes for title and author

Listing 26.28. Safely looking up FieldMetadata from the directory

Listing 26.29. Safely looking up a potentially missing subfield

Listing 26.30. General lookupValue function for looking up tag-subfield code pairs

Listing 26.31. Specific cases of looking up Title and Author

Listing 26.32. Raw MARC records to Maybe Title, Maybe Author pairs

Listing 26.33. Convert Maybe values into Books

Listing 26.34. Putting it all together in processRecords

Lesson 27. The Functor type class

Listing 27.1. Possibly null values: successfulRequest and failedRequest

Listing 27.2. Defining incMaybe to increment Maybe Int values

Listing 27.3. Making Maybe an instance of Functor

Listing 27.4. Examples of using fmaps from one type to another

Listing 27.5. RobotPart defined using record syntax

Listing 27.6. Example robot parts: leftArm, rightArm, and robotHead

Listing 27.7. Rendering a RobotPart as HTML

Listing 27.8. Your RobotPart “database”

Listing 27.9. partVal: a Maybe RobotPart value

Listing 27.10. Using <$> to transform RobotPart to HTML, remaining in Maybe

Listing 27.11. A list of RobotParts

Listing 27.12. Transforming a list of RobotParts to HTML with <$> instead of map

Listing 27.13. The traditional way of transforming a list by using map

Listing 27.14. Turning your partsDB into a Map of HTML rather than RobotParts

Listing 27.15. Simulating a RobotPart coming from an IO context

Listing 27.16. Transforming

Lesson 28. A peek at the Applicative type class: using functions in a context

Listing 28.1. Using a Map as your database of city coordinates

Listing 28.2. Computing the distance between two points with haversine

Listing 28.3. An IO action to handle printing your potentially missing distance

Listing 28.4. One solution to working in a Maybe is to create wrapper functions

Listing 28.5. Using Functor’s <$> operator for partial application in a context

Listing 28.6. The main for dist.hs

Listing 28.7. minOfThree function takes three arguments and returns the smallest

Listing 28.8. A simple readInt IO action made using <$>

Listing 28.9. minOfInts shows using multiple arguments with <*>

Listing 28.10. Your main for min3.hs

Listing 28.11. User data for a game

Listing 28.12. Maybe types for the necessary information to create a user

Listing 28.13. Using Applicative to create a user from IO types

Lesson 29. Lists as context: a deeper look at the Applicative type class

Listing 29.1. A poorly named 2-tuple is still the same thing

Listing 29.2. The trivial Box type doesn’t seem much different from IO

Listing 29.3. A type representing if there are enough resources to continue

Listing 29.4. Nondeterministic possibilities for door values

Listing 29.5. Nondeterministic possibilities for box prizes

Listing 29.6. Deterministic door prize can represent only a single path

Listing 29.7. primesToN, a simple but inefficient primer algorithm

Listing 29.8. Some testNames for your data

Listing 29.9. testIds with different values

Listing 29.10. Sample testScores for testing

Listing 29.11. Same pattern used for IO and Maybe to generate many test users

Lesson 30. Introducing the Monad type class

Listing 30.1. A quick reminder of do-notation

Listing 30.2. Basic setup for the problem of combining two Map lookups

Listing 30.3. Type signature of your goal function, creditsFromId

Listing 30.4. The functions to combine: lookupUserName and lookupCredits

Listing 30.5. altLookupCredits, a solution without using Functor or Applicative

Listing 30.6. Going straight from GamerId -> Maybe PlayerCredits

Listing 30.7. creditsFromId rewritten to use bind instead of pattern matching

Listing 30.8. Adding yet another Map to lookup in order to get a user’s credit

Listing 30.9. You can chain together arbitrarily many lookups with >>=

Listing 30.10. Using >>= to create your echo function

Listing 30.11. Showing the benefit of >> with a verbose version of echo

Listing 30.12. askForName IO action

Listing 30.13. nameStatement works on normal String rather than IO String

Listing 30.14. Your Hello Name program using Monad methods

Lesson 31. Making Monads easier with do-notation

Listing 31.1. helloName

Listing 31.2. Rewriting helloName using do-notation

Listing 31.3. A program illustrating do-notation

Listing 31.4. A trivial IO action in which >>= makes more sense than do

Listing 31.5. The Grade data type code review and culture fit

Listing 31.6. The Degree data type for highest level of education

Listing 31.7. The Candidate data type representing performance on an interview

Listing 31.8. The viable function checks how well your Candidate did

Listing 31.9. Useful IO actions for building your Candidate

Listing 31.10. A single function to read your candidate in from the command line

Listing 31.11. An IO action that lets you know if candidate passed/failed

Listing 31.12. Example candidates

Listing 31.13. Putting your example candidates in a Data.Map

Listing 31.14. Similarity between assessCandidateMaybe and assessCandidateIO

Listing 31.15. A list of possible candidates

Listing 31.16. Assessing a list of candidates using List as a Monad

Listing 31.17. A list-specific way to assess candidates

Listing 31.18. The monadic assessCandidate works on IO, Maybe, and List

Lesson 32. The list monad and list comprehensions

Listing 32.1. The assessCandidateList function from the previous lesson

Listing 32.2. Making a list of pairs by using do-notation

Listing 32.3. evenPowersOfTwo emulates Python’s list comprehensions

Lesson 33. Capstone: SQL-like queries in Haskell

Listing 33.1. A simple Name data type with its Show instance

Listing 33.2. GradeLevel represents the student’s grade

Listing 33.3. The Student data type

Listing 33.4. A list of example students that you can query

Listing 33.5. The _select function is just fmap

Listing 33.6. _where allows you to filter your queries

Listing 33.7. Check whether a String starts with a particular character using startsWith

Listing 33.8. A Teacher data type

Listing 33.9. A list of example teachers

Listing 33.10. Course data type references a Teacher by ID

Listing 33.11. A list of example courses

Listing 33.12. You need a way to pleasantly combine _join, _select , and _where

Listing 33.13. _hinq function allows you to restructure your query

Listing 33.14. Using _hinq allows you to approximate SQL syntax in Haskell

Listing 33.15. One possible solution to a missing _where

Listing 33.16. _select, _where, and _join functions can work for all monads

Listing 33.17. runHINQ function allows you to execute HINQ queries

Listing 33.18. Because it’s written for monads you can query Maybe types

Listing 33.19. An example of a Maybe query

Listing 33.20. You can join Maybe data and easily handle the case of missing data

Listing 33.21. Enrollment relates a Student to a Course

Listing 33.22. A list of example enrollments

Listing 33.23. Queries students and the course they’re enrolled in

Listing 33.24. Running a query for studentEnrollments

Listing 33.25. Joining studentEnrollments with courses

Listing 33.26. Running the englishStudentsQ query to list English students

Listing 33.27. getEnrollments queries your data for enrollments

Lesson 34. Organizing Haskell code with modules

Listing 34.1. The definition in Prelude of head

Listing 34.2. The definition of the Monoid type class

Listing 34.3. Oops, you accidentally created a function that already has a name!

Listing 34.4. An example list that’s a list of values that are an instance of Monoid

Listing 34.5. Explicitly defining a module for your code

Listing 34.6. A first draft of your Main module

Listing 34.7. The Palindrome.hs file

Listing 34.8. Importing only a specific subset of functions from Data.Char

Listing 34.9. The code in your module for properly detecting palindromes

Listing 34.10. Performing a qualified import of your Palindrome module

Listing 34.11. Using the qualified Palindrome.isPalindrome function

Listing 34.12. Your Main.hs file that uses your Palindrome.hs file

Lesson 35. Building projects with stack

Listing 35.1. The default Main module generated by stack

Listing 35.2. The default Lib module generated by stack

Listing 35.3. Rewriting Palindrome from the preceding lesson to work with Text

Listing 35.4. Writing the Main.hs file for your palindrome checker

Lesson 36. Property testing with QuickCheck

Listing 36.1. Small refactor to Main.hs file so you can focus on your Lib.hs file

Listing 36.2. A minimal definition of isPalindrome

Listing 36.3. Iteratively testing and fixing isPalindrome

Listing 36.4. The contents of Spec.hs generated by stack

Listing 36.5. A minimal function for unit testing

Listing 36.6. Your Spec.hs file with a few simple unit tests

Listing 36.7. Adding another test to your main IO action

Listing 36.8. Another minimal fix for the issues in your isPalindrome function

Listing 36.9. Your code is starting to get a bit cleaner

Listing 36.10. Expressing the property you want to test in a function

Listing 36.11. Modified palindrome-testing.cabal file

Listing 36.12. Using the quickCheck function in your Spec.hs file

Listing 36.13. Refactoring preprocess based on feedback from QuickCheck

Listing 36.14. Fixing the issue with punctuation the correct way

Listing 36.15. You can tell QuickCheck to run as many tests as you’d like

Listing 36.16. Refactoring your Lib module to use Data.Text instead of String

Listing 36.17. Refactoring Spec.hs to work with Data.Text

Lesson 37. Capstone: Building a prime-number library

Listing 37.1. Your modified Main module in app/Main.hs

Listing 37.2. Changing src/Lib.hs to src/Primes.hs

Listing 37.3. Modifying primes.cabal to reflect the change of your library module

Listing 37.4. Recursive implementation of the sieve of Eratosthenes

Listing 37.5. Creating a list of all possible primes

Listing 37.6. Using sieve to generate a reasonable list of primes

Listing 37.7. A more robust version of isPrime

Listing 37.8. Changing test-suite in primes.cabal to include QuickCheck

Listing 37.9. Adding necessary imports to test/Spec.hs

Listing 37.10. prop_validPrimesOnly tests that you get Nothing and Just values

Listing 37.11. Adding prop_validPrimesOnly to your main

Listing 37.12. Testing that numbers your function thinks are prime, are prime

Listing 37.13. Testing that the nonprimes are composite numbers

Listing 37.14. Modifying your main to test your additional properties

Listing 37.15. Fixing the bug in isPrime

Listing 37.16. Updating your prop_validPrimesOnly after updated isPrime

Listing 37.17. An unsafe version of your prime factorization algorithm

Listing 37.18. Wrapping unsafePrimeFactors to make it safe

Listing 37.19. Making sure the product of your factors is the original value

Listing 37.20. Ensuring that all your factors are prime

Listing 37.21. Your final main in src/Spec.hs to run all your property tests

Lesson 38. Errors in Haskell and the Either type

Listing 38.1. A function that easily causes an error when used but compiles fine

Listing 38.2. An identical function to myTake, which throws a compiler warning

Listing 38.3. myHead, an example of throwing an error

Listing 38.4. Using Maybe to make head a complete function

Listing 38.5. A safer version of myTake using maybeHead instead of head

Listing 38.6. A safer version of head written using Either

Listing 38.7. isPrime refactors to use multiple messages when a number is invalid

Listing 38.8. The PrimeError types for representing your errors as types

Listing 38.9. Making PrimeError an instance of Show

Listing 38.10. Refactoring isPrime to use PrimeError

Listing 38.11. Translating your isPrime result to be human-readable

Listing 38.12. The main to check for primes from user input

Lesson 39. Making HTTP requests in Haskell

Listing 39.1. The imports for your app/Main.hs file

Listing 39.2. Modifying your project’s .cabal file

Listing 39.3. Variables that will be helpful in making your HTTP requests

Listing 39.4. Placeholder code for your main action

Listing 39.5. The code for building an HTTPS request for the API

Listing 39.6. buildRequest rewritten with the state saved as variables

Listing 39.7. Your final main for writing your request to a JSON file

Lesson 40. Working with JSON data by using Aeson

Listing 40.1. Your Main.hs file

Listing 40.2. Adding your build depends on language extensions

Listing 40.3. A straightforward Book type

Listing 40.4. Adding deriving Generic to your Book type

Listing 40.5. Making your Book type an instance of both FromJSON and ToJSON

Listing 40.6. Taking a Book type and converting it to JSON

Listing 40.7. Taking a JSON representation of your book and converting it to a Book

Listing 40.8. Parsing JSON that doesn’t match your type

Listing 40.9. An example of JSON you don’t have control over

Listing 40.10. Unfortunately, you can’t model this JSON by using Haskell

Listing 40.11. Haskell code that works but doesn’t match the original JSON

Listing 40.12. Making ErrorMessage an instance of FromJSON

Listing 40.13. Values for constructing an ErrorMessage in a Maybe context

Listing 40.14. With your custom FromJSON, you can now parse your JSON

Listing 40.15. Creating an error message to test your instance of ToJSON

Listing 40.16. The JSON from the NOAA has a nested structure

Listing 40.17. Use NOAAResult type to print the names of the data sets

Listing 40.18. Making NOAAResult an instance of FromJSON

Listing 40.19. Using Generic to derive the FromJSON instance for Resultset

Listing 40.20. Making the Metadata type

Listing 40.21. Putting all your types together into a NOAAResponse type

Listing 40.22. Printing the results

Listing 40.23. Putting everything together into your main

Lesson 41. Using databases in Haskell

Listing 41.1. The app/Main.hs file starter code

Listing 41.2. The changes to build-depends in db-lesson.cabal

Listing 41.3. Use the OverloadedStrings extension in db-lesson.cabal

Listing 41.4. The code for building your database

Listing 41.5. The definition of Tool, which should live in app/Main.hs

Listing 41.6. The User data type

Listing 41.7. Making User and Tool instances of Show

Listing 41.8. addUser action connects to database and inserts a user

Listing 41.9. withConn lets you abstract out connecting to the database

Listing 41.10. Checking out by adding the toolId and userId to checkedout

Listing 41.11. The definition of the FromRow type class

Listing 41.12. Making User and Tool instances of FromRow

Listing 41.13. Printing users from your database

Listing 41.14. A generic way to run any queries of tools from your database

Listing 41.15. Safely selecting a Tool by ID

Listing 41.16. updateTool updates your tool

Listing 41.17. Safely updating your database

Listing 41.18. updateToolTable combines all the steps for updating the tool table

Listing 41.19. Checking in a tool with checkin

Listing 41.20. Making sure your tool is updated when it’s checked in

Listing 41.21. Organizing your database actions

Listing 41.22. performCommand organizes all the commands the user can enter

Listing 41.23. Your final main IO action

Lesson 42. Efficient, stateful arrays in Haskell

Listing 42.1. An example of a reasonably large list of 10 million values

Listing 42.2. Your UArray, also containing 10 million values

Listing 42.3. Doubling the values in aLargeList impacts performance

Listing 42.4. Creating a zero index array of Bool

Listing 42.5. An array indexed starting with 1

Listing 42.6. A UArray representing beans in buckets

Listing 42.7. Updating your UArray the functional way with //

Listing 42.8. A first sketch of your listToSTUArray function

Listing 42.9. The full code for copying a list to an STUArray

Listing 42.10. You can treat listToUArray as a pure function

Listing 42.11. A common way of working with STUArrays and runSTUArray

Listing 42.12. Sample data created using listArray

Listing 42.13. Your implementation of bubbleSort