#readwise
# Monads
<div>
<img src="https://blog.ploeh.dk/content/binary/functors-applicatives-monads.png" style="background: white; padding: 10px; width: 250px" />
</div>
## Metadata
- Author: [[Mark Seemann]]
- Full Title: Monads
- URL: https://blog.ploeh.dk/2022/03/28/monads/
## Summary
This is article is a part of a bigger blog series that covers various topics from category theory. The series includes other articles on the topic of functors. Here's a list, retrieved on March 17, 2023.
- [[Kleisli composition]]
- [[Monad laws]]
- [The List monad](https://blog.ploeh.dk/2022/04/19/the-list-monad)
- [The Maybe monad](https://blog.ploeh.dk/2022/04/25/the-maybe-monad)
- [An Either monad](https://blog.ploeh.dk/2022/05/09/an-either-monad)
- [[The Identity monad]]
- [The Lazy monad](https://blog.ploeh.dk/2022/05/30/the-lazy-monad)
- [Asynchronous monads](https://blog.ploeh.dk/2022/06/06/asynchronous-monads)
- [The State monad](https://blog.ploeh.dk/2022/06/20/the-state-monad)
- [The Reader monad](https://blog.ploeh.dk/2022/11/14/the-reader-monad)
- [The IO monad](https://blog.ploeh.dk/2023/01/09/the-io-monad)
- [[Test Data Generator Monad]]
## Highlights
<div>
<img src="https://blog.ploeh.dk/content/binary/functors-applicatives-monads.png" style="background: white; padding: 10px; width: 400px" />
</div>
---
**All monads are [[Applicative Functors]], but not all applicative functors are monads. As the set diagram reiterates, applicative functors are functors, but again: not necessarily the other way around.** ([View Highlight](https://read.readwise.io/read/01gvzswr23kbrymbn69wmfzzzt))
---
When working with functors, you sometimes run into situations where the containers nest inside each other. Instead of a `Functor<decimal>`, you may find yourself with a `Functor<Functor<decimal>>`, or maybe even an object that's thrice or quadruply nested.
If you can flatten such nested functor objects to just `Functor<T>`, then that functor also forms a monad. ([View Highlight](https://read.readwise.io/read/01gvzsxtsgnpydqfhsjrf236e3)) ^2ilhw4
---
**Usually**, however, **you don't see monads introduced via `join` or `Flatten`. It's a shame, really, because it's the most straightforward description.** ([View Highlight](https://read.readwise.io/read/01gvzszwrvw66dj61wv54xnm2y)) ^dbujzg
---
Most languages that come with a notion of monads define them via a function colloquially referred to as *monadic bind* or just *bind*. In C# it's called `SelectMany`, [F# computation expressions](https://docs.microsoft.com/dotnet/fsharp/language-reference/computation-expressions) call it `Bind`, and Scala calls it `flatMap` (with a vestige of the concept of flattening). ([View Highlight](https://read.readwise.io/read/01gvzt10hk41cjqzm836fydj4j))
---
It looks almost like a functor's `Select` method (AKA `map` or `fmap` function). The difference is that this `selector` returns a functor value (`Functor<TResult>`) rather than a 'naked' `TResult` value.
When a `Flatten` (or `Join`) method already exists, you can always implement `SelectMany` like this:
```csharp
public static Functor<TResult> SelectMany<T, TResult>(
this Functor<T> source,
Func<T, Functor<TResult>> selector)
{
Functor<Functor<TResult>> nest = source.Select(selector);
return nest.Flatten();
}
```
([View Highlight](https://read.readwise.io/read/01gvzt2x962cyvz7jy9sw6kr1x))
---
You can use `SelectMany` like this:
`Functor<TimeSpan> source = Functor.Return(TimeSpan.FromMinutes(32));`
`Functor<double> dest = source.SelectMany(x => Functor.Return(x.TotalSeconds + 192));`
The lambda expression returns a `Functor<double>`. Had you called `Select` with this lambda expression, the result would have been a nested functor. `SelectMany`, however, flattens while it maps (it *flatMaps*). (This example is rather inane, since it would be simpler to use `Select` and omit wrapping the output of the lambda in the functor. The later articles in this series will show some more compelling examples.) ([View Highlight](https://read.readwise.io/read/01gvzt59fvs6ddqjn4fddw9b31))
---
If you already have `Flatten` (or `Join`) you can always implement `SelectMany` like this. Usually, however, languages use monadic bind (e.g. `SelectMany`) as the foundation. Both C#, Haskell, and F# do that. In that case, it's also possible to go the other way and implement `Flatten` with `SelectMany`. ([View Highlight](https://read.readwise.io/read/01gvzt62r1zvfm07n3z0ah4xwg))
---
**The ability to flatten nested functors is the essence of what a monad is.** There are, however, also some formal requirements. As is the case with functors, there are laws that a monad should obey. ([View Highlight](https://read.readwise.io/read/01gvztb8n8qryke1ahe75hktgh))
---
Another requirement is that in addition to `SelectMany`/`bind`/`flatMap`/`>>=` a monad must also provide a method to 'elevate' a value to the monad. This function is usually called *return*. ([View Highlight](https://read.readwise.io/read/01gvztbphpvb4ma3p9y388nte8))
---
**A monad is a functor you can flatten.** That's the simplest way I can put it. ([View Highlight](https://read.readwise.io/read/01gvztd0kwn11fqw8tj118dq5s)) ^se5abr
---