haskellmonadscategory-theorymonoids# A monad is just a monoid in the category of endofunctors, what's the problem?

## A monoid is...

### ...satisfying these laws:

## A monad is...

### ...satisfying these laws:

Who first said the following?

A monad is just a monoid in the category of endofunctors, what's the problem?

And on a less important note, is this true and if so could you give an explanation (hopefully one that can be understood by someone who doesn't have much Haskell experience)?

Solution

That particular phrasing is by James Iry, from his highly entertaining *Brief, Incomplete and Mostly Wrong History of Programming Languages*, in which he fictionally attributes it to Philip Wadler.

The original quote is from Saunders Mac Lane in *Categories for the Working Mathematician*, one of the foundational texts of Category Theory. Here it is in context, which is probably the best place to learn exactly what it means.

But, I'll take a stab. The original sentence is this:

All told, a monad in X is just a monoid in the category of endofunctors of X, with product × replaced by composition of endofunctors and unit set by the identity endofunctor.

*X* here is a category. Endofunctors are functors from a category to itself (which is usually *all* `Functor`

s as far as functional programmers are concerned, since they're mostly dealing with just one category; the category of types - but I digress). But you could imagine another category which is the category of "endofunctors on *X*". This is a category in which the objects are endofunctors and the morphisms are natural transformations.

And of those endofunctors, some of them might be monads. Which ones are monads? Exactly the ones which are *monoidal* in a particular sense. Instead of spelling out the exact mapping from monads to monoids (since Mac Lane does that far better than I could hope to), I'll just put their respective definitions side by side and let you compare:

- A set,
**S** - An operation,
**• : S × S → S** - An element of
*S*,**e : 1 → S**

*(a • b) • c = a • (b • c)*, for all*a*,*b*and*c*in*S**e • a = a • e = a*, for all*a*in*S*

- An endofunctor,
(in Haskell, a type constructor of kind**T : X → X**`* -> *`

with a`Functor`

instance) - A natural transformation,
, where**μ : T × T → T***×*means functor composition (*μ*is known asin Haskell)`join`

- A natural transformation,
, where**η : I → T***I*is the identity endofunctor on*X*(*η*is known asin Haskell)`return`

*μ ∘ Tμ = μ ∘ μT**μ ∘ Tη = μ ∘ ηT = 1*(the identity natural transformation)

With a bit of squinting you might be able to see that both of these definitions are instances of the same abstract concept.

- couldn´t match type 'IO´ with ´[]` inside a do
- How does the Haskell compiler handle the 'where' statement?
- Why is the Factory pattern not needed in Haskell? And how are the needs that pattern addresses in OOP addressed in Haskell?
- Aeson : generics with default values
- Is there a Haskell compiler or preprocessor that uses strict evaluation?
- Python: Haskell-like . / $
- Make GHC deduce one type family constraint from another
- How to listen for window closing in X11 code?
- Can this generic DFS implementation in Haskell be used to detect cycles in an adjacency list?
- Do I need to understand how Haskell represents data to be able to write good Haskell programs?
- substitution in proofs with recursive formulas
- XMonad, spawn floating window right above focused window
- Example of using `linkOnly` from the async library
- How do I read what's in a binary tree in Haskell?
- When can a pointful function be refactored to be point free?
- Unable to compile first Haskell Programme in VSCode
- Does Haskell have something like gensym in Racket?
- Unknown error in Haskell that prevents a function from running
- Compiling Haskell (.hs) in windows to a exe
- How to build and modify source code locally of a package from Hackage using the `Haskell Stack`?
- How do I flip a juicy pixel image saved from glut
- Haskell at a user level
- Haskell WinGHC Running Program with Performance Statistics
- How can I check file permissions of a Linux file using Haskell?
- Searching for Reverse Dependencies on Hackage
- Unsafe coerce and more efficient Agda code (-ftrust-me-im-agda)
- Pattern match where type has constructors
- Is Haskell a strongly typed programming language?
- How do I overload a certain operator in haskell to take different types on either side?
- How can I use contradictory evidence?