# Monads and do Notation — Haskell

Source: https://www.geekswithgeeks.com/en/haskell/a-monad

> Sequence dependent effects with >>= and do notation, and build a State monad.

## Sequencing where each step depends on the last

**`Monad`** adds **`>>=`** ("bind"): `m >>= k` runs `m`, takes its result and passes it to `k`, which decides the **next** computation. This allows each step to **depend on previous results**, which `Applicative` cannot express. **`do` notation** is syntactic sugar for chains of `>>=`: `x <- action` binds a result, `let` binds pure values, and the last line is the result. Each monad gives `>>=` its own meaning: for `Maybe` and `Either`, stop at the first failure; for lists, try every possibility (non-determinism); for **`IO`**, perform effects in order; for **`State s`**, thread a state value through computations; for **`Reader r`**, share a read-only environment; for **`Writer w`**, accumulate a log. The **monad laws** (left identity, right identity and associativity) ensure that refactoring do blocks behaves predictably. Monads are not about side effects in general; they are a common interface for **sequencing computations in a context**. Building a small `State` monad by hand, as below, demystifies them; in practice, use `Control.Monad.State` from the `mtl` package.

## A State monad from scratch

Functor, Applicative and Monad instances, then do notation.

```haskell
newtype State s a = State { runState :: s -> (a, s) }

instance Functor (State s) where
  fmap f (State g) = State $ \s -> let (a, s') = g s in (f a, s')

instance Applicative (State s) where
  pure a = State $ \s -> (a, s)
  State f <*> State g = State $ \s ->
    let (h, s1) = f s
        (a, s2) = g s1
    in (h a, s2)

instance Monad (State s) where
  State g >>= k = State $ \s ->
    let (a, s1) = g s
    in runState (k a) s1

get :: State s s
get = State $ \s -> (s, s)

put :: s -> State s ()
put s = State $ \_ -> ((), s)

freshOrderId :: State Int String
freshOrderId = do
  n <- get
  put (n + 1)
  pure ("o-" ++ show n)

threeOrders :: State Int [String]
threeOrders = do
  a <- freshOrderId
  b <- freshOrderId
  c <- freshOrderId
  pure [a, b, c]

main :: IO ()
main = print (runState threeOrders 100)    -- (["o-100","o-101","o-102"],103)
```

## An assembly line with a decision at each station

A monad is an assembly line where each station looks at what arrived and decides what the next station should do. The kind of line (Maybe, IO, State) decides the house rules: stop when a part is missing, carry a clipboard of state along, or actually press buttons in the real world.

**Quiz:** What can Monad express that Applicative alone cannot?

- [x] Computations where later steps depend on the results of earlier ones
- [ ] Pure values
- [ ] Mapping over lists
- [ ] Equality checks

*Answer:* Computations where later steps depend on the results of earlier ones. Bind passes each result to a function that chooses the next computation.
