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
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
Lesson 3. Lambda functions and lexical scope
Lesson 4. First-class functions
Listing 4.2. ifEvenDouble and ifEvenSquare
Listing 4.6. addressLetter v.1
Listing 4.7. sfOffice, nyOffice, renoOffice
Lesson 5. Closures and partial application
Listing 5.1. ifEvenInc, ifEvenDouble, ifEvenSquare
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
Lesson 6. Lists
Lesson 7. Rules for recursion and pattern matching
Lesson 8. Writing recursive functions
Lesson 9. Higher-order functions
Lesson 10. Capstone: Functional object-oriented programming with robots!
Listing 10.1. Constructor for a basic cup object
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.2. Common types Char, Double, and Bool
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
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.13. getName, getAge, getBloodType
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
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.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
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
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
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
Lesson 20. Capstone: Time series
Listing 20.1. Imports for time_series.hs
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.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
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
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
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
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
Lesson 31. Making Monads easier with do-notation
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
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
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
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
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