Hacker News new | past | comments | ask | show | jobs | submit login

Because monads are abstract, and very general, there turn out to be many different ways to think of monads, and each of the perspectives is enlightening in its own way. In fact, really the ONLY thing that monads provide is an abstraction for many concepts that you probably are already familiar with. In Haskell, the Monad type class simply allows you to use the same syntax for these different operations.

In other programming languages, I'm sure you already use the very same functions that are fundamental to monads; you just don't have a syntactic construct that says "Hey, these things share a similar structure!"

Most of the other replies focus on IO (and on the do-notation side of things), and so I'm not sure that they'll help your confusion.

We'll need to start with functors. Without getting too formal, functors describe "containers" that can hold objects of any type. A list is a functor, a "Maybe" is a functor, the result of a computation (i.e., "IO") is a functor… lots of things are functors!

And since functors can contain anything, they can certainly recursively contain themselves - that is, they can be nested! We can have a list of lists, or a "Maybe (Maybe a)" (hey,… that seems like an awfully redundant thing to construct). When we talk about "IO", we can have an "IO (IO a)": that is, we can describe a computation that returns to us another computation!

And with these functors that I've mentioned, we realize something interesting: We would often like to flatten these nested structures. We use "concat" to reduce a list of lists to just a list; how to reduce a "Maybe (Maybe a)" to a "Maybe a" is obvious; for IO, we might want to take our description of a computation that returns a description of another computation ("IO (IO a)") and convert that into a description of a computation that runs the first computation, and upon receiving the result of that computation (which is a computation itself), run the resulting computation, and then return the result of THAT as our final result.

Also, for these things, we have an idea of how we would inject a pure value into the structure. We can create a list with a singleton element, or "Just" our element, or the computation that does nothing interesting (no missile launches) and just returns our element.

Haskell is just wacky enough to let us use the same syntax for all of these rather different ideas (which only share the similarity of having the monadic structure)!

NOW, I personally don't think that the trouble that people have with monads is related to the abstraction and the shared syntax - I think it has more to do with the use of the use of Haskell's "do" notation. Learn what "do" notation is sugar for! Learn what "bind" (>>=) is (it's basically a neat combination of the two operations ("bind" and "return", for what it's worth) that I described above).

I can't promise you that learning monads is something necessarily pragmatic (except for the fact that I think Haskell is the perhaps the MOST pragmatic language, and you'll need to learn monads to be comfortable with Haskell). But the world would be a pretty dull place if we only did what was pragmatic.




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

Search: