Hacker News new | past | comments | ask | show | jobs | submit login
Intro to Monads (new chapter of Learn You a Haskell for Great Good) (learnyouahaskell.com)
69 points by ab9 on Aug 25, 2010 | hide | past | favorite | 23 comments



I read "Categories for the working mathematican" by Saunders Mac Lane and "The Typeclassopedia" by Brent Yorgey before I really understood monads.

If i just waited for this, it could have spared me all this reading ;-)


Always loving bonus500's style. It's striking, though, how often guides to monads crop up on sites like HN. No matter how many introductions or "monads for idiots" type articles get written, it seems they're conceptually difficult enough to always need more ;-)


Hmm, well, monads are overcomplicated by people writing the tutorials, IMHO. There's a popular one about burritos and spacesuits that makes no sense.

Here's my take: invoking a function is like writing an email to it. It replies with a direct answer to your question and a PS at the bottom mentioning some interesting trivia. Sometimes you are more interested in the PS than the main message body. That's monads.


IMO the main reason this overcomplication tends to happen is that many of the Monads for Idiots guides are written by people just out of the period where they struggled with the concept, and they mistakenly think that the entire thought process that led them to get it is the best way to present the topic.

But teaching doesn't work that way, and more often than not presenting the 'long way' through a topic obscures the essential simplicity that actually helps people figure it out for themselves.

That burrito one is a good example; maybe interesting once you already know what's going on, but if you don't it's most likely just going to frighten you away.


That is the problem with the book Real World Haskell. The authors will spend most of the chapter showing you the wrong way to do it, then a paragraph at the end saying BTW this is the right way.

Kinda sorta the point of having any sort of pedagogical aid, like a book, is that it gives you at least a prod in the right direction. Learning something just to need to unlearn it a few pages later wastes everyone's time.


My take: Monads were created to allow pure functional languages like Haskell to have side effects, particularly input and output, without breaking the pure functional syntax. Monads have many other uses, but state and side effects was the original raison d'etre.

Haskell, for example, is a pure functional language that doesn't have an explicit syntax for side effects or state. But a language without any side effects can not do anything more useful than heat up the CPU: you have to have input and output, which means allowing for side effects. The Monad was the most elegant solution presented for that issue.

In code a monad looks like a function which has more outputs then inputs, and the compiler takes care of channeling the additional input and output between functions adjacent to the monad in way that doesn't break the functional syntax. This differential between function inputs and outputs allows for some interesting use cases and thus the many varieties of monads. Also the compiler makes sure the order lazy evaluations dependent on monads happen in the right order so that you're not trying to parse file contents before you've read the file (because in a pure functional language, like cells in a spreadsheet, everything is intended to be evaluated all at once).


This is because monads are terrifically useful for doing a number of things, but each thing is most easily explained in different, seemingly inconsistent mental models. Monads are an abstract, complicated category theory thing (it's a monoid on the category of endofunctors on the category of Haskell types, obviously!) and trying to explain the concept directly is too hard, so people talk about burritos and E-mails and other things that more reflect specific uses of monads than the general thing.


I'm one of the people who diligently reads each of these things on monads because I know I don't understand them yet. Right now, I at least understand some examples of monads (Maybe, IO, etc.) and why they're used, but the internals of how they work (and what "context" they carry) are still too fuzzy, even if I think I sorta understand the three monad laws (i.e. monads can bind and return values so you can get normal data in and out of them, as well a property reminiscent of function composition that allows them to be chained).

I think I may have to break down and read the O'Reilly book on Haskell (I've never looked for it, but I'm assuming one exists), because the tutorials all seem to use Haskell syntax nowadays and that keeps me from fully understanding many of the articles, even though I seem to be learning bits and pieces of Haskell each time I read one of these.


The O'Reilly book would be Real World Haskell: http://book.realworldhaskell.org/

It is very good, and expressly isn't a monad tutorial in the usual style, although they do get covered eventually of course (but from memory without any extra emphasis or allusions to difficulty, magic, etc).


I am working my way through RWH at the moment. Its biggest flaw is that you have to work your way through it, in order. Don't care about reading barcodes? Tough, because you can't read the later chapter on Monads unless you grit your teeth.

The authors spend an awful lot of time showing you the wrong way (i.e. non-idiomatic) to do something and revealing with a flourish the Haskell way. Really you ought to just skip the first half of each chapter and not waste time learning techniques that you have to unlearn later. But you can't, because of the way it's all so intertwined.

Latest peeve - sometimes they talk about wrapping and unwrapping values, which is fine. But sometimes they talk about "peeling". What's that? Is it just another word for unwrap? Is it some special Haskell term? I don't know, I'm a beginner!

On page 369 of my copy there's code that fails to compile and in the session output in the book there are actual error messages from the compiler - but the following paragraph of text talks about it as if it was giving the "correct" results...

The only reason to read RWH is that there's a dearth of Haskell books so you make the best of it - but compared to say Learning Python or Programming Python also from O'Reilly it's really quite poor.


It has been a while since I've read it (as a rusty but not novice haskell programmer), but most of that does actually ring true. I do remember the error message now that you mention it! I assume the code was run automatically when the book was compiled.

There were a reasonable amount of typos and similar errors I seem to recall now actually, which is either surprising or perhaps revealing given that it was publicly reviewed.

That said, I still think it's a good book. I'm not that fussed by having to work through it; that's just how some books are constructed if they're not reference material, particularly when earlier chapters are pre-requisites. I take your point though.

As I said it has been a while, but I don't recall being perturbed by the non-idiomatic->idiom transition either. The numerous monad tutorials mentioned in other comments are a great example of how forcing a particular learning path on someone doesn't always work, but by the same token I believe it can be useful to gently show a common path from common naive code to idiom for example.

I'd still recommend it anyway, if just for the "real world" approach of the title.


<blockquote> There were a reasonable amount of typo and similar errors I seem to recall now actually, which is either surprising or perhaps revealing given that it was publicly reviewed.</blockquote>

A lot of people with Ph.D.s in Computer Science provided "comments" on the book, but did not necessarily review the whole book. Reviewing a book cover to cover takes time. I found a lot of academic mistakes in Real World Haskell, such as the fact they used the phrase "strong typing" which has pretty much been banned from academic programming language literature thanks to Benjamin Pierce's book Types and Programming Language, where Pierce says he reviewed tons of papers trying to decipher a common meaning for the phrase and couldn't. A better way to characterize a type system is by whether it is (a) sound (b) complete.

There were just too many examples in Real World Haskell where it could've been much better explained, especially considering the authors CVs.


Thank you.


Monads are hard to explain because they name a pattern that most programmers have probably implemented before, but on the surface don't seem to have all that much in common with other examples. It doesn't help that the terminology used to describe them is either very abstract/mathy, or complete gibberish (burritos and spacesuits? riiiiight...). Many monad descriptions read like talking about the botany of fruit in the abstract, rather than describing tomatoes and bananas and then what properties they have in common.

You're on the right track about chaining and function composition. Monads remind me of Unix pipes, but with hooks for extensibility (such as Maybe's short circuiting), and with static checking of their guarantees. I also don't really care for Haskell, but I've implemented monads in Lua, OCaml, and Scheme.


It doesn't help that "bind" and "return" seem completely backwards to me due to knowing C. Even when I listed the properties in GP post, I see that I wrote it in a way that implies that they work the wrong way.

No matter how I think about it, using return to put data into a monad just seems weird. Maybe I have to think of it as returning a monad? Which leaves bind. What do I have to imagine doing? Kidnapping the value and leaving the context behind?

Burritos and spaceships indeed.


I tried to avoid the names entirely (also: ">>="?). I don't really use Haskell, though, so it's easy for me to just recognize when a monadic interface is a useful abstraction and leave it at that.

Besides, a lot of languages have weird terminology.


Hmm, in Chapter 10 ==> means one thing and in Chapter 11 it means something different! CHapter 11 (Testing and Quality Assurance) being the buggiest so far...

Oh dear.


The "return" keyword in Haskell was poorly-chosen, it already has too much meaning in the imperative world associated with it. "inject" or "insert" or even "save" would have been much better.


While I won't give you my own personal "Omg, monads are ..." lecture, what I will say is this:

When they finally clicked for me... I felt like it was something so simple, and I was seriously overcomplicating it in my head, and wondered why they were so frustrating all along. I had a similar experience with NoSQL, actually.

RWH is an excellent book, you should certainly check it out.


1. Use GHCi to check types and ideas. 2. Write your own monads. How about a monad for (->) e? (It already exists, but so what?)

That's at least the strategy that works best for me.


Though I definitely didn't finish reading this, I couldn't help but remember Why's Poignant Guide to Ruby (http://mislav.uniqpath.com/poignant-guide/) - this is probably the prettiest Haskell learning resource writeup I've seen up to date :)


I like how the author contrasts monads with applicative functors and demonstrates why monads are more powerful.


Looking forward to his dead-tree book.




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

Search: