Hero roadmap: the whole course on one page
| All 50 lessons | |
| How to practice | |
| The capstone, revisited | |
| Where to go next |
All 50 lessons
Fifty Haskell lessons, five stages. Start at lesson one and move forward in order: every page ends with a link to the next one. The whole map is below, so you can also jump straight to the topic that brought you here.
Start: 01-10
- Lesson 01: What is Haskell and why it matters
- Lesson 02: Install the toolchain with GHCup
- Lesson 03: GHCi: the interactive shell
- Lesson 04: Your first program
- Lesson 05: Values with let and where
- Lesson 06: Types and type signatures
- Lesson 07: Functions and application
- Lesson 08: Currying and partial application
- Lesson 09: Operators, sections, and fixity
- Lesson 10: if, guards, and pattern guards
Language core: 11-20
- Lesson 11: case expressions
- Lesson 12: Pattern matching
- Lesson 13: Tuples
- Lesson 14: Lists
- Lesson 15: Ranges and enumeration
- Lesson 16: List comprehensions
- Lesson 17: Recursion replaces loops
- Lesson 18: map, filter, and foldr
- Lesson 19: Lambdas and composition
- Lesson 20: Type classes
Types and abstractions: 21-30
- Lesson 21: Parametric polymorphism
- Lesson 22: Maybe and null safety
- Lesson 23: Either and recoverable errors
- Lesson 24: data: product types
- Lesson 25: data: sum types
- Lesson 26: Records
- Lesson 27: newtype and type synonyms
- Lesson 28: Recursive data: binary trees
- Lesson 29: Functor
- Lesson 30: Applicative
Effects and tooling: 31-40
- Lesson 31: Monad
- Lesson 32: do notation
- Lesson 33: IO and purity
- Lesson 34: Files and IO
- Lesson 35: Modules and imports
- Lesson 36: Cabal projects
- Lesson 37: Dependencies
- Lesson 38: Testing with HUnit
- Lesson 39: Property testing with QuickCheck
- Lesson 40: Laziness and infinite lists
Real programs: 41-50
- Lesson 41: Strictness and space leaks
- Lesson 42: Folds
- Lesson 43: Monoids
- Lesson 44: Traversable
- Lesson 45: Monad transformers
- Lesson 46: Errors and exceptions
- Lesson 47: Concurrency
- Lesson 48: Parsing with Megaparsec
- Lesson 49: Capstone: a todo CLI
- Lesson 50: Hero roadmap: the whole course on one page
How to practice
Read one lesson, type every snippet by hand, then break it on purpose and read the compiler error. The error messages are the fastest teacher in the language, and they get better the more you provoke them.
Keep the loop tight: write the signature, write the body, compile, fix the first error only. When a definition refuses to typecheck for more than twenty minutes, replace the body with undefined and check the signature in GHCi with :t.
The capstone, revisited
The todo CLI from lesson 49 is a skeleton for a larger project. Each of these extensions uses a different part of the course, and none of them requires a new idea:
- Storage: swap the text file for JSON with aeson, keeping the pure core unchanged.
- Parsing: replace the hand written argument parser with the Megaparsec grammar from lesson 48 and get better errors.
- Errors: move the file operations into ExceptT so that a missing file becomes a typed failure instead of an exception.
- Concurrency: load several files at once with mapConcurrently and keep a shared counter in a TVar.
- Tests: add a QuickCheck property that adding then removing a task returns the original list.
Where to go next
Four directions continue naturally from here. Pick the one that matches the program you want to write, not the one that looks most advanced:
-- web services
servant, warp, wai, aeson
-- data and streaming
conduit, streaming, vector, cassava
-- effects and architecture
mtl, transformers, effectful, polysemy
-- correctness
property tests, liquidhaskell, formal methods
Two books carry the next stage well: Real World Haskell for breadth and Haskell in Depth for production concerns. The Development section has neighbouring courses if you want a second language to compare against.
Rebuild the capstone from memory without reopening lesson 49. Then extend it with one item from the list above and keep the tests green at every step. The course ends; the practice does not.
Next: Haskell course
Article author: Arthur Isaev