4 ms·
I've always struggled to grok the concept of monads. Worth the 2 minute read.
by selbekk 7y ago
I've always struggled to grok the concept of monads. Worth the 2 minute read.
- mbrock 7y agoAnother way to say it: a monad is a generic type with the sufficient API to do binding sequences like x <- fetch "foo" y <- frob x return (x + y) The meaning of binding/sequencing is decided by the particular monad instance. This is why it's a useful formalism to represent things like asynchronous I/O (you make the sequencing mean promise chaining), abortable computations (you make the sequencing cancel when it sees failure values), combinatorial/nondeterministic programming (you make it so one binding can happen several times). Monads are also closely related to continuation-passing style or delimited continuation capture, and those techniques can also be used to implement everything monads can.
- tylerhou 7y agoExcept this “simple” metaphor isn’t too useful. For monads like IO and State, “monad as a container” is a stretch. And some don’t fit at all — the list monad often is imagined as a computational context with nondeterminism, not simply a container. https://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-tutorial-fallacy/ https://byorgey.wordpress.com/2009/01/12/abstraction-intuiti...
- mikekchar 7y agoI don't really understand your point of view. Especially the list monad is literally a list. The shape of bind for the list monad is [a] -> (a -> [b]) -> [b]. If that's not a container, I don't know what is. The fact that it can be used to solve problems where the list represents a non-deterministic result is really secondary. I mean, I suppose you can think of it as being different, but it seems a lot more complicated in my mind. I think some "containers" a definitely hard to envision. A partially applied function is also a monad (i.e. it's trivial to write a meaningful bind for it). It may be hard to think of a partially applied function as "containing" the applied parameters, but I still think that's easier than any other way of envisioning it. But maybe it's a matter of horses for courses.
- pjc50 7y agoFor IO, the monad is a "box" you put the entire mutable universe in so you can pretend the rest of your program is stateless.
- chombier 7y agoA monad is for composing computations with effects: let's say you have some function f:: a -> b returning some b, but now you need the computation to happen with some extra effect (throwing exception, changing state, futures, etc). A way to model effects is to have f :: a -> Tb, where T is a type constructor encapsulating a value of type b produced with some effect. Let's call this new f a T-program, then a monad is exactly what you need to compose T-programs nicely. The monad "return" is the simplest T-program, and the monad "bind" helps you compose T-programs: given another T-program g :: b -> Tc, you cannot simply compose g with f since the types don't match. However, the bind operator >>= :: (b -> Tc) -> Tb -> Tc gives you a function (>>= g) :: Tb -> Tc which does compose with f, producing a new T-program: a -> Tc. So now you can compose T-programs, yay! The monad laws ensure that T-programs form a category, which is to say that composition works the right way. So a monad is just the plumbing you need to compose computations with effects in a nice way.
- the_af 7y ago> A monad is for composing computations with effects To nitpick: that's only one particular use of some monads.
- mbrock 7y agoIt's pretty close to how both Moggi and Wadler formulated it in their respective seminal papers which introduced monads for representing different notions of computations in functional languages.
- chombier 7y agoWell of course, but arguably there's not much space between "monads-as-containers/burritos" and "monoids-in-the-category-of-endofunctors" presentations... If you know a better one in between I'm all ears :)