A monad is a type-constructor interface for computations that carry some context while producing values. The context may represent optionality, generated values, parsing, parallel work, state, or I/O; the interface does not prescribe what happens internally. Instead, it identifies a shared way to build a value with `unit` and sequence a context-aware next step with `flatMap`. section 11.5 section 11.7
The motivating clue is repeated code. `Gen`, `Parser`, and `Option` can each combine two contextual values with the same `flatMap` and `map` structure, even though their meanings differ. A `Monad[F]` factors out that structure: implementing `unit` and `flatMap` for `F` supplies derived operations such as `map` and `map2` once for every instance. section 11.2 section 11.2.1
Listing 11.1 Implementing map2 for Gen, Parser, and Option
extension [A](fa: Gen[A])
def map2[B, C](fb: Gen[B])(f: (A, B) => C): Gen[C] = #1
fa.flatMap(a => fb.map(b => f(a, b)))
extension [A](fa: Parser[A])
def map2[B, C](
fb: Parser[B])(f: (A, B) => C
): Parser[C] = #2
fa.flatMap(a => fb.map(b => f(a, b)))
extension [A](fa: Option[A])
def map2[B, C](
fb: Option[B])(f: (A, B) => C
): Option[C] = #3
fa.flatMap(a => fb.map(b => f(a, b)))
Compare the identical `map2` implementations: only the surrounding type changes, revealing the abstraction that Monad captures. section 11.2
`flatMap` matters when the value produced by one computation determines the computation to run next. Unlike `map2`, which combines already chosen computations, it can select later work from an earlier result. This makes monadic computations context-sensitive: an `Option` lookup can use a retrieved ID for later lookups, and a parser can choose a row parser after reading a file header. section 12.3.1 section 12.3.2
A Monad provides a small primitive vocabulary and many reusable combinators:
- `unit(a)` lifts a value into the context `F[A]`. section 11.2.1
- `flatMap(f)` sequences a function from `A` to `F[B]`, retaining the context rather than producing a nested result. section 11.2.1 section 12.3
- `map` transforms a produced value, and `map2` combines two monadic values; both are derived from the primitives. section 11.2.1
- `sequence`, `traverse`, `replicateM`, `product`, and `filterM` package common patterns for any monad. section 11.3
The interface is constrained by laws, not merely method signatures. Associativity says regrouping chained `flatMap` calls cannot change their result. Left and right identity say that inserting `unit` before or after sequencing changes nothing. These guarantees justify refactoring a sequence of computations without altering its meaning. section 11.4.1 section 11.4.3
Stateful indexing
For `State[S, A]`, `flatMap` passes the updated state from one action to the next. A `zipWithIndex` computation can read an integer state, emit it beside a list element, increment the state, and continue. Once `State[S, _]` has a Monad instance, generic `sequence` and `replicateM` can run repeated state actions in order. section 11.5.2 section 11.7
Monad extends Functor, so every monad supports `map`; it also has capabilities beyond an Applicative. `unit` and `map2` can combine a fixed computation structure, but cannot implement `flatMap` or `join`, which remove a layer of context and enable later structure to depend on earlier results. section 12.3 section 12.9
This sequencing is useful for explicit effects as well. An `IO[A]` value can describe input and output while retaining its result type; `flatMap` builds a larger description, and interpretation later executes it. The same generic monadic combinators can then express repeated reads, loops, and effectful folds. section 13.2.1





