Learn Haskell
Will Kurt
  • MEAP began June 2016
  • Publication in June 2017 (estimated)
  • ISBN 9781617293764
  • 400 pages (estimated)
  • printed in black & white

Haskell is unlike any other programming language. It's purely functional with a strong type system and lazy evaluation. In practical terms, this means that Haskell treats programs a lot like math, so you have to think more than you type. Along with being arguably the most interesting language, Haskell has the reputation of being one of the most challenging programming languages to learn. Learning Haskell doesn't have to be difficult, and this book can help!

Learn Haskell teaches you the Haskell language and functional programming concepts while you hack on interesting problems that you'll find challenging but never frustrating. This example-filled tutorial will take you from beginning concepts to tackling the tough topics, like Monads, easing you along the way with increasingly sophisticated examples. You'll find lots of crystal-clear illustrations, hands-on exercises that reinforce the concepts, and open-ended tasks that encourage you to hack and explore Haskell on your own. By the time you're done, you'll be able to use Haskell as a platform for having fun with code and possess a deep understanding of functional programming.

Table of Contents detailed table of contents

Lesson 0 Getting Started with Haskell

0.1 Welcome to Haskell

0.1.1 The Haskell Platform

0.1.2 Text Editors

0.2 The Glasgow Haskell Compiler (GHC)

0.2.1 Basic GHC Usage

0.3 Interacting with Haskell - GHCi

0.4 Writing and working with Haskell code

0.4.1 Interactively writing Haskell programs

0.5 Exercises

Unit 1: Functional Programming

Lesson 1 Functions and Functional Programming

1.1 Functions

1.2 Functional Programming

1.3 The Value of Functional Programming in Practice

1.3.1 Variables

1.3.2 Variables that are Variable

1.4 Summary

1.5 Answers to Quick Checks

Lesson 2 Lambda Functions and Lexical Scope

2.1 Lambda Functions

2.2 Writing our own Where clause

2.3 From Lambda to Let: Making our own variable variables!

2.4 Practical Lambda Functions and Lexical Scope

2.5 Summary

2.6 Answers to Quick Checks

Lesson 3 First Class Functions

3.1 Functions as Arguments

3.1.1 Lambda Functions as arguments

3.1.2 Example - custom sorting

3.2 Returning Functions

3.3 Summary

3.4 Answers to Quick checks

Lesson 4 Closures and Partial Application

4.1 Closures - Creating Functions with Functions

4.2 Example: Generating URLs for an API

4.2.1 Partial Application: Making Closures Simple

4.3 Putting it all together

4.4 Summary

4.5 Answers to Quick checks

Lesson 5 Lists

5.1 The anatomy of a list

5.2 Lists and Lazy Evaluation

5.3 Common Functions on Lists

5.4 Summary

5.5 Answers to Quick Checks

Lesson 6 Rules for Recursion and Pattern Matching

6.1 Recursion

6.1.1 Rules for recursion

6.1.2 Our First Recursive Function: Greatest Common Divisor

6.1.3 Pattern Matching

6.2 Summary

6.3 Answers to Quick Checks

Lesson 7 Writing Recursive Functions

7.1 Review: Rules of Recursion

7.2 Recursion on Lists

7.3 Pathological Recursion: Ackerman Function and the Collatz Conjecture

7.4 Summary

7.5 Answers to Quick checks

Lesson 8 Higher Order Functions

8.1 Map

8.2 Abstracting away recursion with map

8.3 Filtering a list

8.4 Folding a list

8.5 Summary

8.6 Answers to Quick Checks

Lesson 9 Capstone: Functional Object Oriented Programming with Robots!

9.1 An object with one property: A cup of coffee.

9.1.1 Creating a constructor

9.1.2 Adding accessors to our object

9.2 A more complex object: Let’s build fighting robots!

9.2.1 Sending messages between objects

9.3 Why Stateless programming matters

9.4 Types - Objects and so much more!

9.5 Summary

9.6 Exercises

Unit 2: Introducing Types

Lesson 10 Type Basics

10.1 Types in Haskell

10.2 Function Types

10.2.1 Functions for converting to and from Strings

10.2.2 Functions with Multiple Arguments

10.2.3 Types for First Class functions

10.3 Type Variables

10.4 Summary

10.5 Answers to Quick checks

Lesson 11 Creating our own types

11.1 Type Synonyms

11.2 Creating new types

11.3 Record Syntax

11.4 Summary

11.5 Answers to Quick checks

Lesson 12 Type Classes

12.1 Further Exploring Types

12.2 Type classes

12.3 The Benefits of Type Classes

12.4 Defining a Type class.

12.5 Common Type Classes

12.5.1 The Ord and Eq Type classes

12.5.2 Bounded

12.5.3 Show

12.6 Deriving Type classes

12.7 Summary

12.8 Answers to Quick checks

Lesson 13 Using Type Classes

13.1 A type in need of classes

13.2 Implementing Show

13.3 Type Classes and Polymorphism

13.4 Default Implementation and Minimum complete definitions

13.5 Implementing Ord

13.6 To Derive or Not to Derive?

13.7 Type classes for more complex types

13.8 Type class roadmap

13.9 Summary

13.10 Answers to Quick checks

Lesson 14 Capstone: Secret Messages!

14.1 Ciphers for Beginners: ROT13

14.1.1 Implementing our own ROT Cipher

14.1.2 The rotN algorithm

14.1.3 Rot encoding a String

14.1.4 The problem with decoded odd-sized alphabets

14.2 XOR: the magic of cryptography!

14.3 Representing values as Bits

14.4 The one-time pad

14.4.1 Implementing our one-time pad

14.5 A Cipher Class

14.6 Summary

14.7 Extensions

Unit 3: Programming in Types

Lesson 15 Creating Types with "and" and "or"

15.1 Product Types - Combing types with 'and'

15.1.1 The curse of product types: Hierarchical design.

15.2 Sum types: Combining Types with 'or'

15.3 Putting together our books store

15.4 Summary

15.5 Answers to Quick checks

Lesson 16 Design by Composition - Semigroups and Monoids

16.1 Intro to composability - Combining Functions

16.2 Combining like Types: Semigroups

16.2.1 The Color Semigroup

16.2.2 Making Color associative and using Guards

16.3 Composing with Identity: Monoids

16.3.1 mconcat: Combining multiple Monoids at once.

16.3.2 Monoid Laws

16.4 Practical Monoids - Building Probability Tables

16.5 Summary

16.6 Answers to Quick checks

Lesson 17 Parameterized Types

17.1 Types that take arguments

17.1.1 A more useful parameterized type: Triple

17.1.2 Lists

17.2 Types with more than one parameter

17.2.1 Tuples

17.2.2 Kinds: Types of Types

17.2.3 Data.Map

17.3 Summary

17.4 Answers to Quick checks

Lesson 18 The Maybe Type: Dealing with missing values

18.1 Introducing Maybe : Solving missing values with types

18.2 The problem with Null

18.2.1 Handling missing values with errors

18.2.2 Returning Null values

18.2.3 Maybe as a novel solution to missing values

18.3 Computing with Maybe

18.4 Back to the Lab! More complex computation with Maybe

18.5 Summary

18.6 Answers to Spot Quizzes

Lesson 19 Capstone: Time Series

19.1 Our data and the TS data type

19.1.1 Building a Basic Time Series Type

19.2 Stitching together our TS data using Semigroup and Monoid

19.2.1 Making TS an Instance of Monoid

19.3 Performing calculations on our Time Series

19.3.1 Calculating the min and max values for our time series

19.4 Transforming Time Series

19.4.1 Moving average

19.5 Summary

19.6 Extensions

Unit 4: IO in Haskell

Lesson 20 "Hello World!" - Introducing IO Types

20.1 IO Types - Dealing with an impure world

20.1.1 Examples of IO Actions

20.1.2 Keeping values in the context of IO

20.2 Do-notation

20.3 An example: Command line Pizza cost calculator

20.3.1 A peak at Monads - Do notation in Maybe

20.4 Summary

20.5 Answers to Quick checks

Lesson 21 Interacting with the Command line and Lazy IO

21.1 Interacting with the command line the non-lazy way

21.2 Interacting with Lazy IO

21.2.1 Thinking of our problem as a lazy list.

21.3 Summary

21.4 Answers to Spot Quizzes

Lesson 22 Working with Text and Unicode

22.1 The Text Type

22.1.1 When to use Text vs String

22.2 Using Data.Text

22.2.1 OverloadedStrings and Haskell extensions

22.2.2 Basic Text utilities

22.3 Text and Unicode

22.3.1 Searching Sanskrit

22.4 Text IO

22.5 Summary

22.6 Answers to Quick checks

Lesson 23 Working with Files

23.1 Opening and closing files

23.2 Simple IO tools

23.3 The Trouble with Lazy IO

23.4 Strict IO

23.4.1 When to use Lazy vs Strict

23.5 Summary

23.6 Answers to Spot Quizzes

Lesson 24 Working with Binary Data

24.1 Working with binary data using ByteString

24.2 Glitching JPEGS

24.2.1 Inserting Random Bytes

24.2.2 Sorting random bytes

24.2.3 Chaining together IO Actions with foldM

24.3 ByteStrings, Char8 and Unicode

24.4 Summary

24.5 Answers to Quick checkzes

Lesson 25 Capstone: Processing Binary Files and Book Data

25.1 Working with Book Data

25.2 MARC Records

25.2.1 The Structure of a MARC record

25.2.2 Getting the data

25.2.3 The Leader and Iterating through our records

25.2.4 Reading the Directory

25.2.5 Using the directory to look up fields

25.2.6 Processing the directory entries and looking up MARCFields

25.2.7 Getting Author and Title information from a Marc Field

25.3 Putting it all together

25.4 Summary

25.5 Extending the Exercise

Unit 5: Introduction: Working with type in a context

Lesson 26 The Functor Type Class

26.1 An Example: Computing in a Maybe

26.2 The Functor Type Class

26.3 Functors are everywhere!

26.3.1 One interface for Four very different Problems

26.3.2 Converting a Maybe RobotPart to Maybe Html

26.3.3 Converting a list of RobotParts to a List of Html

26.3.4 Converting A Map of RobotParts to Html

26.3.5 Transforming an IO RobotPart into IO Html

26.4 Summary

26.5 Answers to Quick checks

Lesson 27 A peek at the Applicative Type Class: Using Functions in a Context

27.1 A command line application for calculating the distance between cities

27.1.1 The limitations of Functor

27.2 Using <*> for partial application in a context

27.2.1 Introducing the <*> operator

27.2.2 Using <*> to finish our city distance program

27.2.3 Using multi-argument function in IO using <$> and <*>

27.3 Using <*> to create data in a context

27.3.1 Creating a User in the Context of a Maybe

27.4 Summary

27.5 Answers to Quick checks

Lesson 28 Lists as Context: A deeper look at the Applicative Type Class

28.1 Introducing the Applicative type class

28.1.1 The pure method

28.2 Containers vs Contexts

28.3 List as a Context

28.3.1 Container vs context

28.3.2 A game show example

28.3.3 Generating the First N prime numbers

28.3.4 Quickly generating large amounts of test data

28.4 Summary

28.5 Answers to Quick checks

Lesson 29 Introducing the Monad Type class

29.1 The Limitations of Applicative and Functor

29.1.1 Combining two Map lookups

29.1.2 Writing a not-so-trivial echo IO Action

29.2 The bind operator: >>=

29.3 The Monad Type class

29.3.1 Using Monad to build a Hello <Name> program

29.4 Summary

29.5 Answers to Quick checks

Lesson 30 Making Monads Easier with Do-notation

30.1 Do-notation revisited

30.2 Using do-notation to reuse the same code in different contexts

30.2.1 The problem setup

30.2.2 The IO context - Building a command line tool

30.2.3 The Maybe Context - Working with a Map of Candidates

30.2.4 The List Context - Processing a list of Candidates

30.2.5 Putting it all together and writing a Monadic function

30.3 Summary

30.4 Answers to Quick checks

Lesson 31 The List Monad and List Comprehensions

31.1 Building lists with The List Monad

31.1.1 The guard Function

31.2 List comprehensions

31.3 Monads: much more than just lists

31.4 Summary

31.5 Answers to Quick checkes

Lesson 32 Capstone: SQL-like queries in Haskell

32.1 Getting Started

32.2 Basic queries for our list: Select and Where

32.2.1 Implementing _select

32.2.2 Implementing _where

32.3 Joining Course and Teacher data types

32.4 Building our HINQ interface and example queries

32.5 Making a HINQ type for our queries

32.6 Running our HINQ queries

32.6.1 Using HINQ with Maybe types

32.6.2 Joining multiple lists to get all enrollments

32.7 Summary

32.8 Extending the Exercise

Unit 6 : Introduction

Lesson 33 Organizing Haskell code with Modules

33.1 What happens when we write a function with same name as one in Prelude?

33.2 Building a multi-file program with modules

33.2.1 The Main module

33.2.2 Putting our improved isPalindrome code in its own module

33.2.3 Using our Palindrome module in our Main module

33.3 Exercises

33.4 Answers to Quick Checks

Lesson 34 Building projects with stack

34.1 Starting a new stack project

34.2 Understanding the project structure

34.2.1 The project .cabal file and autogenerated files

34.2.2 The app, src and test directories

34.3 Writing our code

34.4 Building and running our project!

34.4.1 A quick improvement: getting rid of langauge pragmas

34.5 Exercises

34.6 Answers to Spot Quizzes

Lesson 35 Property testing with QuickCheck

35.1 Starting a new project

35.2 Different types of testing

35.2.1 Manual testing and calling GHCi from stack

35.2.2 Writing our own unit tests and using stack test

35.3 Property testing QuickCheck

35.3.1 Testing properties

35.3.2 Introducing QuickCheck

35.3.3 Using QuickCheck with more types and installing packages

35.4 Exercises

35.5 Answers to Quick checks

Lesson 36 Capstone - Building a Prime Number Library

36.1 Starting our new project

36.2 Modifying the default files

36.3 Writing our core library functions

36.3.1 Defining primes

36.3.2 Defining an isPrime function

36.4 Write tests for our code

36.4.1 Properties for isPrime

36.4.2 Fixing the Bug

36.5 Adding code to factor numbers

36.6 Summary

36.7 Extending this exercise

Unit 7 Introduction

Lesson 37 Errors in Haskell and the Either Type

37.1 Head, Partial Functions and Errors

37.1.1 Head and Partial Functions

37.2 Handling Partial functions with Maybe

37.3 Introducing the Either type

37.3.1 Building a prime check with Either

37.4 Summary

37.5 Answers to Quick checks

Lesson 38 Making HTTP Requests in Haskell

38.1 Getting our project setup

38.1.1 Our starter code

38.2 Using the HTTP.Simple module

38.3 Making an HTTP Request

38.4 Putting it all together.

38.5 Summary

38.6 Answers to Quick checks

Lesson 39 Working with JSON Data using Aeson

39.1 Getting set up

39.1.1 Setting up stack

39.2 Using the Aeson library

39.3 Making our Data types instances of FromJSON and ToJSON

39.3.1 The easy way

39.3.2 Writing our own instances of FromJSON and ToJSON

39.4 Putting it all together: Reading our NOAA Data

39.5 Summary

39.6 Answers to Quick checks

Lesson 40 Using Databases in Haskell

40.1 Setting up our project

40.2 SQLite and setting up our database

40.2.1 Our Haskell Data

40.3 Creating data - Inserting Users and Checking out tools

40.3.1 Adding new users to our data base

40.3.2 Creating checkouts

40.4 Reading data from the data base and FromRow

40.4.1 Making our data an instance of FromRow

40.4.2 Listing Users and Tools

40.5 Updating existing data

40.6 Deleting data from our database

40.7 Putting it all together

40.8 Summary

40.9 Answers to Quick checks

Lesson 41 Efficient, Stateful Arrays in Haskell

41.1 Efficient Arrays in Haskell with the UArray type

41.1.1 The inefficiencies of lazy lists

41.1.2 Creating a UArray

41.1.3 Updating our UArray

41.2 Mutating state with STUArray

41.3 Taking values out of the ST context

41.4 Implementing Bubble sort

41.5 Summary

41.6 Answers to Quick checks

Afterward: Where do you go from here?

What's inside

  • Learn the foundations of Functional Programming
  • Write safe, predictable code with fewer bugs
  • Thinking in types to solve problems
  • Understanding Haskell's unique features
  • Use Monads to solve practical problems

About the reader

Readers should have some experience with JavaScript, Python or Ruby. No functional programming or math skills required.

About the author

Will Kurt currently works as a Data Scientist at Quick Sprout. With a formal background in both Computer Science (MS) and English Literature (BA) he is fascinated with explaining complex technical topics as clearly and generally as possible. He has taught a course section on Haskell at the University of Nevada, Reno and given workshops on Functional Programming. He also blogs about probability at CountBayesie.com.

Manning Early Access Program (MEAP) Read chapters as they are written, get the finished eBook as soon as it’s ready, and receive the pBook long before it's in bookstores.
MEAP combo $44.99 pBook + eBook
MEAP eBook $35.99 pdf + ePub + kindle

FREE domestic shipping on three or more pBooks