Comment by giardini

14 years ago

What makes it difficult to "really comprehend monads"? Why did it take two months for you to really comprehend them?

- I made many mistakes in the learning process. Monads should be done after you know core language (higher order functions, ADTs and pattern matching, typeclasses). I was attempting to learn many things at once and perfectly, instead of climbing Wittgenstein's ladders.

- Getting used to nested functions, \x -> f >>= (\y -> g >>= h x y) is not that easy.

- The type of bind, m a -> (a -> m b) -> m b is rather complex for a noob. You've got polymorphism, and m can be different depending on the monad. Monads form a higher-kinded typeclass * -> * , unlike most other typeclasses * . I discovered Functor rather late. You need to realize Reader r is a monad, not Reader, not Reader r a. Partial application on types.

- It took me some time to read and rederive all standard monads - [], Maybe, Reader, Writer, State, Cont. Those things enter the mind slowly, especially state and continuations. Now I can reimplement all of them given a scratch of paper.

- If you do not know IO, you can only use GHCi to test expressions. I thought I need to know monads very well to do IO. This is not true, but I survived a month by loading modules and interacting with GHCi only. On the other side, after all this trouble IO clicked immediately. Fortunately Haskell has enough concepts you can learn for a month without writing a complete interactive program. Look at http://www.haskell.org/haskellwiki/Blow_your_mind for example.

- After you know (>>=), return you need to learn standard library functions such as join, mapM, sequence, forever etc. Then transformers.

- When I was learning, there was no Learn You a Haskell or Typeclassopedia yet. I found sigfpe's famous http://blog.sigfpe.com/2006/08/you-could-have-invented-monad... very late. I found a lot of useless buzz and opinions but rarely with details or instructive code.

I am happy I had a good curious attitude and did not resign.

I can't speak for the poster you're replying to, but in my personal opinion, monads exist at a higher level of abstraction than most people, even experienced imperative programmers, are accustomed to. The formal definition of a monad is quite simple, but it can be challenging for a newbie to extrapolate from the literal code that defines a monad to see how and why that pattern is widely applicable to so many seemingly distinct, unrelated problem domains. Eventually, through usage, you develop an intuition for it and it seems plainly obvious. But despite the proliferation of "monad tutorials", there are no magic words that bring understanding. Newcomers want to have it explained to them without having to get their hands dirty by writing code, but the only way to really acquire an intuition for something this abstract is through experience.

The other problem I see is that monads are really hyped (over-hyped, in my opinion) as a huge stumbling block for new Haskellers, and this turns out to be something of a self-fulfilling prophecy. By the time you reach the monads chapter of whatever book you're learning from, you've already read 5000 blog posts and HN comments about how difficult and confusing monads are going to be, so you go in expecting to be confused. And this just contributes to the confusion. I think that it's much easier to learn this sort of concept if you can go into it without any preconceived notions about what to expect. But since monads are something that all Haskell users like to talk about, publicly, it's next to impossible to introduce a newbie to the concept without them having already heard about the difficulties they're about to face.

  • This is so true. I managed to covertly teach monads to a coworker who had never heard of monads or functional programming before, all without uttering the word monad. Luckily they were familiar with LINQ notation (which is pretty much do notation) and I used analogies such as wrapping and unwrapping. I used a custom c# maybe type as the concrete example. They were able to intuitively grasp it in a couple of days (whereas it took me about 2 months stumbling through online tutorials learning it myself).

To expand tmhedberg's first paragraph, take the sequencing behavior of any imperative language (represented by the ";", say) and generalize it.