Okay but WTF is a MONAD?????? #SoME2

preview_player
Показать описание
"A monad is a monoid in the category of endofunctors"
Words dreamed up by the utterly insane!!!

In this video I go over the common meme and explain it's origins and show many examples of monads out in the wild!
This video is intended for anyone with programming experience who wants to finally understand what a Monad is all about! Including examples of Monads in practice!

This is my submission for the SOME2:

Also join our discord!

Chapters
0:00 The Famous Line
0:07 Introduction
1:05 Origins
2:11 Peeling Back the Layers
2:26 Monoids
4:34 Categories and Endofunctors
6:18 Revisiting the Quote
6:42 Nerd Alert!!
6:54 Monads in action
7:01 Visual Example
9:00 Quick Correction
9:20 Programming Time
9:29 Haskell
10:12 Important Monads
10:22 Maybe
11:16 Option
11:57 IO Monad
12:25 do notation
12:45 Error Handling
13:18 ?
13:24 List Monad
13:45 List Comprehensions
14:40 Iterators
15:23 Monads in OOP
15:53 Builder Pattern
16:55 Review
17:27 Thank you and Conclusion

GOOD REFERENCES:
Рекомендации по теме
Комментарии
Автор

Hello, for all of those confused about this post not being a meme. Also some clarifications for the future:
This is my submission for the Summer of Math Exposition 2 ran by 3Blue1Brown.
You can find more info here:

I also ran a community poll and the majority voted in favour of this video in particular.
Memes will continue as usual. In the meantime come check out the discord server to let me know what you want to see next (link in desc).
If this does well maybe I'll make some more!

Some clarifications, NO a Monad is NOT A MONOID in the category of endofunctors, it is a Monoid Object in the tensor category, BUT this is significantly harder to explain and I don't want to get into monoidal categories or tensor products. Maybe in another video.

thestemgamer
Автор

A monad is just a monoid in the category of endofunctors

joly
Автор

If you watch the video backwards, it teaches comonads

danielprovder
Автор

Now I can confidently say:

A monad is just a monoid in the category of endofunctors. What's the problem?

BreytnerNascimento
Автор

What's a monad? A monad is a monoid in the category of endofunctors.
What's a monoid? It's what a monad is in the category of endofunctors.
What's an endofunctor? It's the thing that comprises the category in which a monad is a monoid.
What's a category? There are some things you just aren't meant to know.

johnchessant
Автор

This was an amazing video, _especially_ coming from a literal meme channel. You made this video your own with your own style, you're more than just the other manim-using channels that look exactly like 3Blue1Brown but sped up.
This has my vote for sure

NoorquackerInd
Автор

I'm a pure mathematician/physicist that got into programming and it couldn't have been a better combination. More programming concepts should be put in terms of their real mathematical counterparts without fearing people won't understand nor care.

Bankoru
Автор

The editing is so trippy I was more focused on how the hell you did all of that than the actual explanations.
Pro tip: use fairlight's noise suppression tools to remove the background noise, and when recording VsCode, increase the native zoom of the app instead of doing it during editing.

AByteofCode
Автор

In pure functional programming, there is no state. Everything is immutable; and every computation needs to be describeable as a mathematical function. To add to that, GHC (the haskell compiler) was initially made as an experiment to see how well pure functional languages mix with laziness; and it inherits a lot of the ML (Meta Language) roots; which are mainly that they take a lot from mathematics and category theory. It makes sense if you think about it, since category theory works within the bounds of mathematics yet describes a lot of interesting things. And because of that, you have this FP jargon. For most people, they start learning these things with Functors, which you can think of as values inside a box or a context. A couple examples for Functors are 1. lists, where the "context" is multiple values of the same type, and 2. optional values, the context being "this value may not exist", so a `Maybe Int` would be either a `Just Int` or a `Nothing`. These Functors need to have a function `fmap` to map the values under the context. That function for a list type is obvious, it would be `fmap (+1) [1, 2, 3]`, which returns `[2, 3, 4]`. for `Maybe Int`'s, there are two cases. `fmap (+1) (Just 1)` which would return `Just 2`, or `fmap (+1) Nothing` which would be `Nothing`.

Then, something kind of important is getting the concept of Monoids. A simple explanation is that a type would be a monoid if there's a function `a -> a -> a` (`a` being a generic type), this (called `mappend`) function takes 2 `a`s and returns an `a`. it needs to be associative. and finally, there needs to be an "identity" value `mempty`. a value that, if the function was called with mempty and another value of that type, the other value would be returned. An example of a monoid is integers under addition; as that forms a monoid because the "identity" is 0 in addition, and the associative function is `+`. Other monoids are lists and strings. And also, integers are also monoids under multiplication.

Finally, applicative functors. Earlier, with functors; the `fmap` function took a function, and applied it to a value under a context. With applicative functors, even the function is under a context. This is a natural point to get to, because if you had a function that takes more than 1 argument, you'd need applicative functors. They define the operation `ap`, which you'd run as `ap (Just (+1)) (Just 1)`, and you could use with fmap like: `ap (fmap (+) (Just 1)) (Just 2)`. Also, applicatives define a function called `pure` which returns the minimal value in a context; so for a list, `pure 1` would be `[1]`, for a `Maybe Int`, `pure 1` would be `Just 1`, etc.

That was all before monads. See, all monads are applicative functors. They are the most used method of sequencing effects or actions (meanwhile monoids sequence values). And that is the main reason they're used. To easily get an effect ran before the other, maybe bound to a name as well. To get that, they had to also have a way to collapse contexts; so make a `Just (Just 1)` become a `Just 1` via the `join` function by `join (Just (Just 1))`. That's necessary because, in a pure world, nesting is one of the only ways to sequence effects. Collapsing that information into one structure makes it easier to work with. that, and also because pure languages only evaluate the outer `IO` context of effects that do I/O. so in a `IO (IO ())` type, the outer one would be evaluated whatever it does, with the inside one being ignored. Monads allow them both to be evaluated by collapsing the contexts.

And people call monads "a monoid in the category of endofunctors" for a reason; first off, all functors in haskell are endofunctors. secondly, let's look back at 2 important functions. the `pure` function, which is of the type `a -> m a`, and the `join` function, which is of the type ` m (m a) -> m a` . if you squint (i can make this more equivalent but it'd take me writing much more in YT comment), then these functions are like the mempty and mappend in the context of functors. `pure` is like `mempty` because, if you use natural transformations, it'd be `() ~> m`, which is isomorphic (meaning equal or similar) to mempty, since mempty returns a value like `mempty :: a`, it is isomorphic to a function that has the type `() -> a`, since it cant add more data. `join` is like mappend because it takes 2 functors, similarly to how mappend takes 2 values, and smashes them together into one functor, like mappend smashes values into one value.

subterfugue
Автор

That epic moment when a monad is a monoid in the category of endofunctors

mistakenmeme
Автор

Yessss. I was waiting for a more long-form programming video! This channel is going nuts!

Hadkek
Автор

honestly the restatement of the quote at 1:50 cleared up like 80% of the questions i had (but didn't bother to explore) lmao. thanks for this video

lbibrzh
Автор

I've always had them explained to me as:

Functor: anything with a map method (e.g. array, future, list)

Monoid: anything appendable (string, array, list, future)

Endofunctor: anything that you can map to it's same category

Monad: anything with a flatmap method

Which yeah, lots of "normal", boring things like lists fall into that category, but that's the point. The only things that are excluded are the hard things (like state), so you can focus on that stuff in one place rather than spread out throughout your whole program.

trannusaran
Автор

Good video, I was struggling with the explanations of a monad as a begginer programmer and mathmatician, you are a great teacher, and the editing is on point :cheffkiss:

rodrovelasquez
Автор

This is incredibly fascinating, and really well explained! Please do make another one of these! Other than that I have only one thing to say: the editing is pretty insane. It's clean and fluid and snappy, and I can tell you know your way around Manim.

on the other hand, because everything was constantly moving, and some code was on screen for barely a second after it was typed out... I couldn't keep my eyes on any one spot to take in what's being written. That made some scenes feel way busier than they had to, and it was super distracting!

So for your next one I'd just recommend slowing down the pace a bit, and toning down the editing slightly. That'll make everything easier to follow.

ilonachan
Автор

You bring up Rust, which does have Option and Result as true monads, with the Try trait acting as a limited form of the Monad type class (traits and type classes are basically just the same thing), but implemented a little more obtusely due to Rust's type system.

Iterators in Rust though I'm not sure are truely monads, because I don't think they're actually endofunctors. Monoids and functors yes as far as I'm aware, but not _endofunctors._ This is because Iterator is not one type, but is its own trait, and the bind operator (called flat_map) doesn't actually give the same type as the previous iterator, but rather a completely different type that still implements the Iterator trait. Effectively flat_map :: a i -> (i -> b j) -> FlatMap (a i) (i -> b j). The output has a completely different context from the input. This is because 1) Every function in Rust has its own type to help with static dispatch, and 2) this is how Rust makes its iterators lazy without native lazy evaluation.

angeldude
Автор

I was reading the whole categories for working mathematics book just to understand what a monad is. This video came up in my feed at the perfect time.

srijan
Автор

After watching it taking the Linear algebra class in university and watching it now again I finally understand the whole thing even through the (German) language barrier in math terms.
This video is really amazing thank you.

redcrafterlppa
Автор

Well done. Hope the submission does well. Was both entertaining and informative.

Jordans
Автор

This has been one of the best descriptions I've heard. I already knew some Haskell and understood the concepts (both monoid and monads) but seeing the graphical examples, seeing the translation of the expression was really great!

Great content, congratulations for being so awesome

SierisimoSier