Category Theory

Monads: Endofunctors with Extra Structure

JavaScript's async/await, Rust's Result<T,E>, Haskell's Maybe - all monads. One abstraction, three languages, billions of lines of production code. Promise.then() is bind. async/await is syntactic sugar over a monad. Every time one writes await, that is a Kleisli chain in action.

  • Promise/async-await in JavaScript: monad for asynchrony
  • fp-ts, cats, Arrow: monads in production TypeScript/Scala/Kotlin
  • Haskell IO monad: language purity while working with side effects
  • Optional in Java, Result in Rust: variants of the Maybe/Either monad

Monad: the Category-Theoretic Definition

JavaScript's Promise, Rust's Result, Haskell's IO - all share the same mathematical structure: a **monad**. A monad on a category C is a triple (T, η, μ) where T: C → C is an endofunctor, η: Id ⇒ T is a natural transformation (unit, "return"), and μ: T² ⇒ T is a natural transformation (multiplication, "join"). Three diagrams must commute: associativity and two unit laws.

**Historical note:** Monads appeared in mathematics in the 1950s (Grothendieck, Godement), and were introduced into programming by Eugenio Moggi (1991) and Philip Wadler (1992 - 1995). The famous phrase "a monad is just a monoid in the category of endofunctors" (James Iry, 2009) is mathematically precise, though it sounds daunting.

What is μ: T² ⇒ T in a monad?

The Kleisli Category: Composing Effectful Computations

The **Kleisli category** C_T for a monad (T, η, μ) has the same objects as C, but morphisms f: A → B in C_T are arrows A → T(B) in C. These are "effectful" functions: functions returning a wrapped result. The composition of two such arrows implements a chain of effects.

**Monads as "programmable semicolons":** Wadler called monads "programmable semicolons". The bind operator (>>=) is a new form of sequential composition where "something extra" happens between steps (error checking, logging, state management).

How is the composition of two Kleisli arrows f: A → T(B) and g: B → T(C) defined?

Monads in Practice: Maybe, List, IO, State

Monads are a universal pattern for structuring computations with effects. **Maybe** encapsulates partiality, **List** - non-determinism, **IO** - side effects, **State** - mutable state. Each monad is a concrete endofunctor with η and μ.

**Monads in real code:** In fp-ts (TypeScript) and cats (Scala) monads are used in production. Promise in JavaScript is a monad! bind = .then(), unit = Promise.resolve(). Key law: p.then(x => Promise.resolve(f(x))) is equivalent to p.then(f).

What is the type of the join (μ) operation in the List monad?

Key Ideas

  • Monad = endofunctor T + η (unit) + μ (join), satisfying three laws
  • Kleisli category: morphisms A → T(B) with monadic composition
  • bind (>>=) = fmap + join: the tool for chaining effectful computations
  • Maybe: partiality; List: non-determinism; IO: effects; State: state
  • Monad = "programmable semicolon" (Wadler)

Related Topics

Monads tie together functors, natural transformations, and composition.

  • Functors — A monad is a special endofunctor with additional structure
  • Natural Transformations — η and μ are natural transformations that define the monad
  • Adjoint Functors — Every pair of adjoint functors gives rise to a monad

Вопросы для размышления

  • Why does Promise violate one of the monad laws? (Hint: Promise.resolve(Promise.resolve(42)) !== Promise.resolve(42))
  • What would a monad for validation with accumulated errors look like? How does it differ from Either?
  • Prove that (a) => [a] (listUnit) and flat (listJoin) satisfy the monad laws for List.

Связанные уроки

  • plt-30-io-monads
  • plt-31-algebraic-effects
Monads: Endofunctors with Extra Structure

0

1

Sign In