an absolutely horrible explanation of monads

There are lots of blog posts, videos, etc explaining monads, usually in the context of a programming language like Haskell, Scala, and so on. At this point, it's a cliche to explain what monads are, but I'm going to do it anyway. Instead of stopping at "here's how monads work," I'll also add some observations about using them in practice.

First off, it's good to know some things about Haskell and its type system before reading this. You can also dive in without having that background knowledge, but it might be harder to get anything out of this post. I also recommend reading this monad explainer, because it does a really good job explaining the mechanics of monads.

Anyway, imagine a league of wizards who create magic boxes. Each wizard has their own special style of box, in terms of design and shape. Some boxes are blue with yellow stars, some are purple with a silver crescent on each face, some are cubes, some are really small triangular pyramids, and so on. What makes the boxes "magic" is that (1) they can be transfigured into different colors and shapes, and (2) you can cast all sorts of useful spells on them.

There is a wizard who goes by the name of "Winstrius" and is well-respected by the townsfolk, as he creates very high-quality magic boxes. His favorite type is a "cat-carrier" box. You put your cat in the box when you need to take it somewhere (like the vet), and the cat is stored in a pocket dimension. But Winstrius really cares about his cats, so made the box change color based on the cat's mood; if the cat gets too distressed in the pocket dimension, Winstrius will see the box change color and know to take his cat out of the box.

That's cool, you might say, but how does the box know the cat's mood? Well, Winstrius hexed his cat so that it creates a new box around itself when its mood changes. The astute reader might notice a problem with this method: each time the cat changes its mood, the new box gets nested inside the previous one. That means Winstrius would have to unwrap countless boxes to get his cat out, after an average trip to the vet. Thankfully, this doesn't happen, because magic boxes have another useful property.

When a wizard creates a type of box, they can define a way for nested boxes to "join" with their surrounding box. As with the cat box, many boxes function by nesting, so it's obviously very useful to have a way to join boxes, and thus avoid the unwrapping problem. The way you define the "join" magic for each box is significant. For example, with the cat box, joining an `inner` and an `outer` box basically discards the `outer` box, leaving only the `inner` box, which propagates the cat's most recent mood.

Guess what, these boxes are monads! Bet you didn't see that coming! Monads are more or less a way of combining two "wrappers" into a single "wrapper." By this analogy, functors are a way of reaching inside a "wrapper" to do something, while applicatives are a simpler/less powerful way of combining "wrappers".

So maybe you already knew how monads work, or somehow understood the really bad wizard analogy, but still have questions about how to use them in a program. Haskell is all about monads, right? Not really. You might see some people structure their program by rolling a monad stack with all the necessary monads, and then putting all the main code inside that monad. I used to do that, but it's not actually a good idea. Monads are really just a way of abstracting things, and abstractions should only be used when necessary. Just because monads are treated as something fancy and mysterious doesn't mean they're above the usual principles of applying abstractions.