Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It's a design pattern for encapsulation, with similar goals to OO but different methods. Rather than telling you what a monad is, I'll just tell you the goal.

OO is designed to hide the dangerous parts of the world from you. The dangerous parts of the world (or at least some dangerous parts of the world) are encapsulated inside little black boxes with well defined interaction points. If you interact only through those little boxes, you should be safe. For instance, a logger object gives you 1 methods: writeLog (I'll ignore logging levels). The details of actually writing logs are not your business, and you (in principle) don't need to worry about them.

Monads are stricter. A monad puts you into a box and only gives you a few interaction points with the outside world. You can do whatever you want in a monad, but you are never allowed to leave the box. Inside the logger box, you are permitted only pure functions (functions with no side effects) and writeLog.

So basically, in an OO world, code using a logger might call os.unlink("/var/log/myprogram.log"). This would interact in a harmful way with your logging mechanisms. In a monadic world, from inside the logging monad, you are not given access to os.unlink.

Thus, f: a -> Loggable b in the monadic world (where Loggable b is an b living inside the box) is safer than f: (Logger, a) -> b in the OO world.



A monad puts you into a box and only gives you a few interaction points with the outside world. You can do whatever you want in a monad, but you are never allowed to leave the box.

This is not true for many commonly used monads, except for the IO monad. You can extract values from the list monad, Maybe monad, state monad, etc.

Put simply, a monad specifies how values can be wrapped in a 'box', and how such boxes are combined. For instance, Maybe is a box that can contains either a variable or nothing. In Haskell:

data Maybe a = Nothing | Just a

The Maybe monad specifies how expressions resulting in a Maybe are combined. Expressions are evaluated until/unless one of the expressions returns 'Nothing', and the value of the monad becomes Nothing.

Comparably, the IO monad specifies how IO actions are combined, the State monad combines expressions in such a manner to create 'state', etc.

We have tried to illustrate Monads with a Haskell-ish example here:

http://www.nlpwp.org/book/chap-words.xhtml#id3390030


So, a sort of sandbox function?


Yes.

But, more like sandbox type.


Hmm, I see. Does it also execute code, like a sort of exception handler, or is it just for limiting/allowing access to scope?


A monad is a type that has certain associated functions — to wrap values in the monad and do calculations on what's inside. The type itself obviously cannot execute code, but the associated functions obviously do. Monads can be used to implement exceptions.

As an example, lists are monads. The operator for doing calculations with the value in a monad is >>= (pronounced "bind"). To double every item in an array, you could do:

    [1, 2, 3] >>= \n -> [n * 2]
(The syntax "\n -> [n2]" defines a function that takes one argument, n, and returns a list containing n 2.)

There's clearly work going on behind the scenes to pass each value in the list to the associated function as "n", and then combine all the resulting [n * 2] lists into one big list of the same type as the original. But that's all transparent to the programmer. He only sees the interface that the monad offers.


Hmm, I see. The problem with my understanding it is that people are describing its properties and I have to build the mental model from them.

Are Python list comprehensions monads?


Well, it's the type itself that's a monad. So the question would be, are Python lists monads thanks to list comprehensions? And the answer is: Kind of. The idea of a monad in functional programming is that it's a generic type that can have a lot of different implementations.

The two operations that must be defined for a monad are:

• Return: You pass any value and it returns a monad encapsulating that value

• Bind: You pass a function taking an argument of the type wrapped by the monad and returning another value wrapped in the monad, and it returns a value of the monad

With these two operations, you can accomplish a surprising range of tasks. Python borrowed list comprehensions from Haskell, where they are based on monads — but in Python, they're kind of orphaned from their monadic roots.


This makes it much clearer, thanks. Those two operations weren't mentioned anywhere else that I saw, and they are very helpful in explaining what monads are.


Monads have nothing to do with OO. Ignore this guy's comment and read samstokes' instead.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: