Solutions to the Exercises

1.1: Factorials

In this exercise you'll practice the basics of writing and calling Haskell functions by creating a recursive implementation of the factorial function.

1.2: The Fibonacci Sequence

In this exercise you'll once again practice writing and calling recursive Haskell functions. This time, you'll implement a function to calculate a fibonacci number using multiple recursive calls.

1.3: Manual Currying

This is the third exercise in chapter 1. In this exercise you'll get practice with function currying and partial application by implementing your own versions of the curry and uncurry functions.

2.1: Reversing A List With Folds

When you're writing Haskell, it's important to get an intuitive feel for how different high order functions work with the structure of data types like lists. In this exercise you'll develop that intuition by working through an exercise to reverse a list using different fold operations.

2.2: Zipping Lists

This exercise will give you a chance to practice using list comprehensions. You'll build your own version of the zipWith function, with and without comprehensions. As you work through the exercise, you'll learn how to think through different approaches to working with list structures.

2.3: Implementing concatMap

This exercise will help you build on your understanding of common high order functions by building your own implementation of the concatMap function.

2.4: Maps and Folds

In this exercise you'll work on building a better intution for when to use different higher order functions, like map, foldl, and foldr.

2.5: Folds and Infinite Lists

In this exercise you'll reinforce your understanding of folds and laziness by manually stepping through the recursive structure of various fold functions using both finite and infinite lists.

3.1: Undefined

In this exercise you'll expand on what you've learned about `undefined` and designing programs using types by identifying a common cause of errors and thinking about how they can be avoided.

3.2: Understanding Functions by Their Type

In this exercise you'll practice understanding the behavior of functions based on their type. You'll look at several different functions and try to figure out how they'll behave based on their types.

3.3: Filling In Type Holes

In this exercise you'll get some hands on experience with modifying a larger example that is missing part of it's implementaiton. Replacing the use of `undefined` in the example program with the appropriate code will let quickly make a program pass the test case.

4.1: Planting Trees

In this exercise you'll get hands-on experience defining your own data types by creating your own binary tree implementation and writing several functions to support operations on those trees.

4.2: Eval Division by Zero

In this exercise you'll use some of what you've learned throughout the chapter to revisit the `eval` function from your calculator and add error handling.

4.3: Calculator Pretty Printer

In this exercise you'll get the opportunity to improve how you think about the structure of types by building a pretty printer for your calculator. After you've finished this exercise you'll be able to expand your calculator to print your calculator expressions in a more human-readable way.

5.1: Refactoring UserInfo

In this exercise you'll have the opportunity to revisit some examples from earlier in the chapter and refactor them, getting hands-on experience with structuring your code in the process.

5.2: Old New Projects

Apply what you've learned about creating new Haskell projects with this exercise by turning all of your earlier example code into proper stand-aloen projects.

5.3: Document Your Modules

Practice writing good documentation in this exercise by creating documentation for several different projects that you've built so far as you've worked through the book.

6.1: Writing Typeclass Representing Emptiness

Practice writing type classes by creating your own class for optional types. This exercise will give you a chance to cement your understanding of type classes by defining a new type class and creating several instances for it.

6.2: Adding a Default Null Test

Get more comfortable with constraints on type classes and type class instances by expanding on the work from the previous exercise in the chapter. You'll modify an existing type class with a new constraint, and then look at how the new constraint changes the default instances you can write.

6.3: Deriving Nullable

Exercise your understanding of Deriving Via by building type class instances that can be used specifically for deriving instances. Expand on your prior exercise solutions to make it easy to add Nullable instances to new types.

7.1: Thinking about IO Types

This collection of small questions will ask you to reflect on how IO actions work, and how you can manipulate and combine them in various ways. After going through this exercise you'll be in a better position to work through the practical exercise in chapter 8, and you'll have a head start on understanding some of the nuances of working with Monads that you'll encounter in chapter 9.

7.2: Building a Command Line Calculator

Build a command line tool that will let you do basic arithmetic on a list of numbers. As you work through this exercise you'll get more experience working with command line arguments, learn how to deal with common errors in command line programs, and get to try comparing bind and do notation when working with IO actions.

7.3: Building A Word Replacement Utility

Substitute words in a document, get practice with file IO, and see a common approach to handling command line arguments by working through this exercise.

8.1: Handling Terminal Size Edge Cases

Summary TBD

8.2: Do-ing Some Refactoring

Summary TBD

8.3: Refactoring to use Text and Bytestring

Summary TBD

8.4: Viewing Multiple Files

Summary TBD

8.5: Scrolling Backwards

Summary TBD

8.6: Adding A Help Screen

Summary TBD

8.7: Terminal Resizing

Summary TBD

9.1: Flipping the Script

Summary TBD

9.2: Not a Functor

Summary TBD

9.3: The Extended Functor Family

Summary TBD

10.1: traverseDirectoryIO

Summary TBD

10.2: Timing Pure Functions

Summary TBD

10.3: Metrics Strictness

Summary TBD

11.1: Nested FilePacks

Summary TBD

11.2: Building A Real Archival Tool

Summary TBD

11.3: Building A Trace Tool

Summary TBD

12.1: A Configurable Status Line for HCat

Summary TBD

12.2: Command Line Argument Parsing

Summary TBD

12.3: Pretty Printing and Parsing

Summary TBD

13.1: Building Out The Monad Transformer Library

Summary TBD

13.2: A New FilePackParser

Summary TBD

14.1: Handling Correctly Spelled Words

Summary TBD

14.2: Remembering Common Typos

Summary TBD

14.3: Remembering Common Spellchecking in HCat

Summary TBD

15.1: A Complete Data Family Based ShellCommand

Summary TBD

15.2: Better If Expressions

Summary TBD

15.3: Type Level Map

Summary TBD

15.4: Expanded Shell Commands

Summary TBD

15.5: Classless runScript

Summary TBD

15.6: Capstone Project - Build a Terminal Multiplexer

Summary TBD