liveBook · Manning

Monad

As explained in Functional Design and Architecture: Examples in Haskell

A monad is an abstraction that sequences computations while encapsulating a computational context such as optionality, state, errors, or input-output effects.

A monad sequences computations while carrying a context such as optionality, state, errors, input-output operations, or other effects. It separates data from the processes that compute with it. section 1.5.4

Consider retrieving a user, reading the user’s name, and taking its first letter. Each lookup may fail, so every step returns a Maybe value. Nested case expressions correctly propagate Nothing, but the surrounding plumbing obscures the computation’s intent. section 1.5.4

getUserInitials :: Int -> Maybe Char
getUserInitials key =
  case getUser key users of                #1
    Nothing   -> Nothing
    Just user -> case getUserName user of  #2
      Nothing   -> Nothing
      Just name -> Just (head name)

The explicit version handles each possible failure with nested case expressions before producing the user’s initial. section 1.5.4

getUserInitials' :: Int -> Maybe Char
getUserInitials' key = do
  user <- getUser key users       #1
  name <- getUserName user        #2
  Just (head name)

The monadic version expresses the same sequence directly: obtain a user, obtain a name, and construct the result while Maybe propagates failure. section 1.5.4

Monads support several design and implementation roles:

  • Encapsulate effects such as state changes, errors, and input-output operations. section 1.5.4
  • Reduce accidental complexity in functional code, including callback-heavy workflows and parser construction. section 1.5.3
  • Provide a functional interface through an algebraic structure whose operations and invariants can be reused by libraries. section 1.5.4 section 1.3.3

From optional lookups to monadic scripting

The Maybe example sequences database-style lookups without repeating failure branches. At a larger architectural scale, free monadic eDSLs use monadic scripting to express business logic and support interpretable domain-specific languages. section 1.5.4 section 6.4

How Functional Design and Architecture: Examples in Haskell covers it

How deep it goes
Defines monads through contexts and examples, then applies Maybe sequencing, while deferring deeper study to monad transformers and extended examples.
Examples
Uses Maybe-based user lookups, nested case expressions, do notation, and free monadic domain-specific scripting.
What it assumes
Assumes prior knowledge of monads and functional programming while motivating their use through concrete Maybe computations.
What you can do after
Apply monadic sequencing to simplify computations that carry failure or other computational effects.
How it connects
Connects monads with functional programming, functional idioms, design patterns, algebraic data types, interpreters, and monad transformers.

Also explained in

Compare how 6 books explain monad →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Functional Design and Architecture: Examples in Haskell. The section links point to the parts of the book it draws on.