59 lines
1.9 KiB
Text
59 lines
1.9 KiB
Text
---
|
|
title: "Monads: Why and how"
|
|
description: I could not repress the urge to make a monad explainer any longer. Did you know that a monad is a monoid in the category of endofunctors?
|
|
tags: post,short,haskell
|
|
date: 2026-05-06 01:20:10 -5
|
|
---
|
|
|
|
I acknowledge that [the world wide web has one hundred trillion monad explainers.](https://wiki.haskell.org/Monad_tutorials_timeline)
|
|
|
|

|
|
|
|
## Why monads
|
|
In the land of Haskell and friends, we love referential transparency.
|
|
We greatly appreciate that
|
|
```haskell
|
|
let x = 1 in x + x
|
|
```
|
|
will always have the same result as
|
|
```haskell
|
|
1 + 1
|
|
```
|
|
|
|
In languages where (almost) no functions have unmarked side-effects, like Haskell, you can even be confident that
|
|
```haskell
|
|
let x = f y in x + x
|
|
```
|
|
is the same as
|
|
```haskell
|
|
(f y) + (f y)
|
|
```
|
|
|
|
This is a truly excellent property to have, but it causes some problems when your program starts interacting with the world.
|
|
|
|
Aside from referential transparency, we don't want to fix evaluation order if we don't have to;
|
|
giving the compiler more freedom to reorder evaluation lets it perform more optimizations.
|
|
And we always want more optimizations.
|
|
|
|
But, quite often, we *need* things to happen in a specific order.
|
|
|
|
Monads let us do two things:
|
|
1. Order operations
|
|
2. Use past results to decide what to do next
|
|
|
|
## How monads
|
|
Easy:
|
|
```haskell
|
|
class Monad m where
|
|
(>>=) :: m a -> (a -> m b) -> m b
|
|
pure :: a -> m a
|
|
```
|
|
|
|
`>>=`, pronounced `bind`, gives us ordering and lets us use past results to decide what to do next.
|
|
|
|
The fact that it gives us ordering is made more clear if we define `>>`, which ignores its result:
|
|
```haskell
|
|
(>>) :: m a -> m b -> m b
|
|
a >> b = a >>= \_ -> b
|
|
```
|