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

complexFn = do x <- getSomeData y <- computeWith x z <- computeSomeMore y return z

Let's say you have here straightforward imperative code. Of course, a real example would be more complex. But suppose x is now a list and you want to vectorise computeWith. Put your x in a box/monad, let's call it Parallel. Define return and bind to be parallel (bind = par . fmap, or something), and that's it. Transparent parallelism.

Maybe it does numerical algorithms, and you want x to be an interval, or a tuple (value, error). Again, define the corresponding monad. Same thing with non-deterministic computation, amb-like operators, passing state between calls... The code that calls them stays the same.

It also provides type safety for operations. For instance, some Haskell libraries allow programmers to specify a network protocol with monads, then write servers/clients that are statically checked to be correct. All sorts of things like that.

Conceptually, a monad is a box with a tag on it (the name of the monad), and your rules for (1) putting things into it, and (2) applying functions to what's inside. Plus compile-time guarantees that you can't do weird things with them, like mix tags and stuff.



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

Search: