5 ms·
I have to say, I had no idea what monads were before reading that article, and after reading it, I still don't. It sounds like something to get the benefits of
by powera 16y ago
I have to say, I had no idea what monads were before reading that article, and after reading it, I still don't.
It sounds like something to get the benefits of object-oriented programming while using functional programming, but I'm really confused.
- orlandu63 16y agoA monad is an abstraction for composing functions that return values with a context by defining how to compose that context. That's it.
- silentbicycle 16y agoWith the recognition that those functions have a common protocol / interface, and consequently have more in common that is usually noticed. Monads aren't a new thing, rather they're giving a name to a concept that has been hiding in plain sight. Trying to look at them directly is confusing at first, like suddenly being able to explicitly manipulate continuations.
- Rusky 16y agoThink of monads as a design pattern. The reason they're named in Haskell is because that language allows you to name a lot of abstract things that most of the time are either ignored or not made explicit. A monad is a type that keeps some value contained, which is like you said a big part of object-oriented programming. Monads are the use of objects for encapsulation, but a bit more extensible than in regular object-oriented languages. The Maybe monad, called Option in the article, is a type that can hold either some value or Nothing. You have to do a null check to get the value, but because it's a monad, you can use the generic function bind to automate this check. The IO monad is just another application of this idea of containing something - all IO operations have the world as their input and output. This is implicit in most languages, but in Haskell it's explicit. Any value you get from the outside world is hidden inside an IO action, but you can use bind to automate the required passing around of the world. One possible reason for confusion is that you can explicitly do null checks with Maybe but you can't explicitly thread the world around with IO. Maybe's method of direct access is public, but IO's is private. Because the /only/ way to get a value out of an IO operation is with bind, you are guaranteed to have all side effects contained in IO actions.
- barrkel 16y agoDo you understand the three-level distinction between type constructors (i.e. templates like C++, or generics in other languages), classes and instances? Do you understand first-class functions (lambdas)? If you've got those concepts down, you can understand monads. Monads are the name for a particular member of a forth level on that three-level stack of abstractions (call them type classes, as that's what Haskell calls them (though I'm fudging a little here)); a type class is a particular shape for a generic type, in the same way that any given generic type is a particular shape for a class, and a class is a particular shape for an instance. So when people talk about Option/Maybe being a monad, they mean Option/Maybe is a generic type (i.e. a type constructor) which has a certain shape - i.e. has a particular set of methods / functions defined on it. That's the abstraction level of monads out of the way. The next thing to understand is the particular operations required. Monads are like containers for values, but rather than operating on the values directly (e.g. y = f(x)), you instead pass the monad the function you'd like it to apply to the value (e.g. y = x.bind(f)), and it returns you a monad which is logically the wrapper that function applied to its contents. Because the application of the function to the value inside the monad is delegated to the monad itself, it gets to decide what to do with it. In the case of Option/Maybe, it'll only apply the function if the contents aren't empty. In the case of IO, it'll logically buffer up a list of imperative I/O operations which will be logically returned as a result of the main function; and that list of imperative instructions will then be imperatively executed, after the nice and pure Haskell program has finished its unpolluted existence. (That's how it happens logically (assuming there are no cheats available in the language), but not necessarily actually.)
- Rusky 16y agoI really like the shapes explanation. It's a much more explicit version of what I was trying to say.
- othermaciej 16y agoI found this explanation of monads more lucid than most, and it is true that the examples and analogies are usually more confusing than helpful. But what I still don't understand is how monads force sequencing more so than regular function calls and expression evaluation. The very first example is about sequencing but there doesn't seem to be much explanation of how monads are usueful for inducing sequencing in a lazy pure functional context.