People think category theory is weird and confusing, but really it just managed to name things (classes) that before were just "things". One might not know what monad or functor is, but they surely used it and have intuition on how it works.
Right. I don't know how many times I've been exasperated by how monads are perceived as difficult.
Do you understand "flatmap"? Good, that's literally all a monad is: a flatmappable.
Technically it's also an applicative functor, but at the end of the day, that gives us a few trivial things:
- a constructor (i.e., a way to put something inside your monad, exactly how `[1]` constructs a list out of a natural number)
- map (everyone understands this bc we use them with lists constantly)
- ap, which is basically just "map for things with more than one parameter"
Monads are easy. But when you tell someone "well it's a box and you can unwrap it and modify things with a function that also returns a box, and you unwrap that box take the thing out and put it inside the original box—
No. It is a flatmappable. That's it. Can you flatmap a list? Good. Then you already can use the entirety of monad-specific properties.
When you start talking about Maybe, Either, etc. then you've moved from explaining monads to explaining something else.
It's like saying "classes are easy" and then someone says "yeah well what about InterfaceOrienterMethodContainerArrangeableFilterableClass::filter" that's not a class! That's one method in a specific class. Not knowing it doesn't mean you don't understand classes. It just means you don't have the standard library memorized!
People have different "aha" moments with monads. For me, it was realizing that something being a monad has to do with the type/class fitting the monad laws. If the monad laws hold for the type/class then you've got a monad, otherwise not.
So then when you look at List, Maybe, Either, et al. it's interesting to see how their conforming to the laws "unpacks" differently with respect to what they each do differently (what's happening to the data in your program), but the laws are just the same.
The reason this was an aha moment for me is that I struggled with wanting to understand a monad as another kind of thing — "I understand what a function is, I understand what objects and primitive values are, but I don't get that List and Maybe and Either are the same kind of thing, they seem like totally different things!"
It's also important to note that in Haskell and other functional programming languages, there is no implied order of operations. You need a Monad type in order to express that certain things are supposed to happen after other things. Monads can also express that certain things happen "in between" two operations, which is why we have different kinds of Monads and mathematical axioms of what they're all supposed to do.
Outside of FP however, this seems really stupid. We're used to operations that happen in the order you wrote them in and function applications that just so happen to also print things to the screen or send bits across the network. If you live in this world, like most people do, then "flatmap" is a good metaphor for Monads because that's basically all they do in an imperative language[1].
Well, that, and async code. JavaScript decided to standardize on a Monad-shaped "thenable" specification for representing asynchronous processes, where most other programming languages would have gone with green threads or some other software-transparent async mechanism. To be clear, it's better than the callback soup you'd normally have[0], but working with bare Thenables is still painful. Just like working with bare Monads - which is why Haskell and JavaScript both have syntax to work around them (await/async, do, etc).
Maybe/Either get talked about because they're the simplest Monads you can make, but it makes Monads sound like a spicy container type.
[0] The FP people call this "continuation-passing style"
[1] To be clear, Monads don't have to be list-shaped and most Monads aren't.
> Do you understand "flatmap"? Good, that's literally all a monad is: a flatmappable.
Awesome! Now I understand.
> Technically it's also an applicative functor
Aaaand you've lost me. This is probably why people think monads are difficult. The explanations keep involving these unfamiliar terms and act like we need to already know them to understand monads. You say it's just a flatmappable, but then it's also this other thing that gives you more?
People think category theory is weird and confusing, but really it just managed to name things (classes) that before were just "things". One might not know what monad or functor is, but they surely used it and have intuition on how it works.
Right. I don't know how many times I've been exasperated by how monads are perceived as difficult.
Do you understand "flatmap"? Good, that's literally all a monad is: a flatmappable.
Technically it's also an applicative functor, but at the end of the day, that gives us a few trivial things:
- a constructor (i.e., a way to put something inside your monad, exactly how `[1]` constructs a list out of a natural number)
- map (everyone understands this bc we use them with lists constantly)
- ap, which is basically just "map for things with more than one parameter"
Monads are easy. But when you tell someone "well it's a box and you can unwrap it and modify things with a function that also returns a box, and you unwrap that box take the thing out and put it inside the original box—
No. It is a flatmappable. That's it. Can you flatmap a list? Good. Then you already can use the entirety of monad-specific properties.
When you start talking about Maybe, Either, etc. then you've moved from explaining monads to explaining something else.
It's like saying "classes are easy" and then someone says "yeah well what about InterfaceOrienterMethodContainerArrangeableFilterableClass::filter" that's not a class! That's one method in a specific class. Not knowing it doesn't mean you don't understand classes. It just means you don't have the standard library memorized!
People have different "aha" moments with monads. For me, it was realizing that something being a monad has to do with the type/class fitting the monad laws. If the monad laws hold for the type/class then you've got a monad, otherwise not.
So then when you look at List, Maybe, Either, et al. it's interesting to see how their conforming to the laws "unpacks" differently with respect to what they each do differently (what's happening to the data in your program), but the laws are just the same.
The reason this was an aha moment for me is that I struggled with wanting to understand a monad as another kind of thing — "I understand what a function is, I understand what objects and primitive values are, but I don't get that List and Maybe and Either are the same kind of thing, they seem like totally different things!"
1 reply →
Forget programming, everyday business and physics is monadic in function.
And if-then statements are functorial.
These are very general thought patterns.
2 replies →
It's also important to note that in Haskell and other functional programming languages, there is no implied order of operations. You need a Monad type in order to express that certain things are supposed to happen after other things. Monads can also express that certain things happen "in between" two operations, which is why we have different kinds of Monads and mathematical axioms of what they're all supposed to do.
Outside of FP however, this seems really stupid. We're used to operations that happen in the order you wrote them in and function applications that just so happen to also print things to the screen or send bits across the network. If you live in this world, like most people do, then "flatmap" is a good metaphor for Monads because that's basically all they do in an imperative language[1].
Well, that, and async code. JavaScript decided to standardize on a Monad-shaped "thenable" specification for representing asynchronous processes, where most other programming languages would have gone with green threads or some other software-transparent async mechanism. To be clear, it's better than the callback soup you'd normally have[0], but working with bare Thenables is still painful. Just like working with bare Monads - which is why Haskell and JavaScript both have syntax to work around them (await/async, do, etc).
Maybe/Either get talked about because they're the simplest Monads you can make, but it makes Monads sound like a spicy container type.
[0] The FP people call this "continuation-passing style"
[1] To be clear, Monads don't have to be list-shaped and most Monads aren't.
4 replies →
> Do you understand "flatmap"? Good, that's literally all a monad is: a flatmappable.
Awesome! Now I understand.
> Technically it's also an applicative functor
Aaaand you've lost me. This is probably why people think monads are difficult. The explanations keep involving these unfamiliar terms and act like we need to already know them to understand monads. You say it's just a flatmappable, but then it's also this other thing that gives you more?
6 replies →