Welcome to the book that refuses to let monads remain mysterious.
This is not another "monad is just a monoid in the category of endofunctors" explanation. This is a practical, example-driven journey through one of programming's most useful (and unnecessarily feared) patterns.
You'll learn monads through working code in the languages where they shine:
- Haskell - Where monads were born
- Scala - Where monads meet the JVM
- Rust - Where monads solve real-world safety
- TypeScript - Where monads bring sanity to JavaScript
- F# - Where monads feel natural on .NET
- You've heard of monads and want to actually understand them
- You've tried to learn monads and bounced off the academic explanations
- You want practical patterns for handling nulls, errors, and side effects
- You're curious why functional programmers get so excited about this pattern
By the end of this book:
- You'll understand what monads are and why they exist
- You'll recognize monadic patterns you're already using
- You'll be able to use monads confidently in your code
- You'll maybe even enjoy them
-
Introduction: The Monad Conspiracy
- Why everyone says monads are hard
- Spoiler: they're not
-
The Problem: Programming is Messy
- Null references and the billion-dollar mistake
- Error handling that doesn't cascade into madness
- Side effects and pure functions
-
- Something or nothing, never null
- Chaining operations that might fail
- Examples in Haskell, Scala, Rust, TypeScript, F#
-
Either: When Failure Has Details
- Left for errors, Right for success
- Railway-oriented programming
- Real error handling across languages
-
List: The Monad You Already Know
- flatMap is everywhere
- Nondeterministic computation
- Why list comprehensions are monadic
-
- What makes a monad a monad
- The three operations: unit, bind, and join
- Seeing the pattern in the wild
-
- Left identity, right identity, associativity
- Why these aren't just academic
- What breaks when laws are violated
-
- The world is impure, our code doesn't have to be
- Lazy evaluation and effect sequencing
- Functional programming meets reality
-
- Threading state without the mess
- Random numbers, functionally
- When you need mutation but want purity
-
Reader: Dependency Injection, Functionally
- Configuration without globals
- The environment pattern
- Composable context
-
- Accumulating values during computation
- Pure logging
- Audit trails
-
- Future computations
- Why promises are monadic
- Async/await is do-notation
-
Validation: Collecting All Errors
- When Either isn't enough
- Applicative vs Monadic validation
- Form validation that doesn't quit early
-
Monad Transformers: Stacking Effects
- Combining Maybe and IO
- OptionT, EitherT, and friends
- When one monad isn't enough
-
Do Notation: Imperative-Looking Functional Code
- Haskell's do, Scala's for
- Comprehension syntax everywhere
- Desugaring the magic
-
Common Patterns and Antipatterns
- When to use which monad
- When NOT to use monads
- Readability vs abstraction
-
- Domain-specific monads
- When to create one
- Testing your implementation
-
- Case studies from real codebases
- Popular libraries using monads
- Recognizing monadic patterns
-
- Functors, Applicatives, and the family tree
- When simpler abstractions suffice
- The bigger picture
-
- What you've learned
- Where to go from here
- The monad conspiracy revealed
- A: Quick Reference - Monad cheatsheet by language
- B: Further Reading - Books, papers, and resources
- C: Category Theory Lite - For the curious
- D: Setup Guides - Getting your environment ready
All code examples are runnable and available in the /examples directory, organized by language and chapter.
Found a typo? Have a better example? Think a chapter could be clearer? Pull requests welcome!
MIT License - See LICENSE file for details
Let's demystify monads together.