I think it's great that people are excited about Haskell and want to write about it, and it's unfortunate that the author had to deal with a less thank tactful response to their work. I hope the author keeps spending time with Haskell and continues to make time to try to write more and help other people!<p>That said, here is a bit of a long comment on my thoughts about writing about and teaching these things:<p>It's true that teaching Monads, Applicatives, and Functors can be tricky and there are a lot of articles that end up doing more harm than good- either by teaching things that are outright incorrect, or more often, teaching people a particular way to use them but setting people up for a lot of trouble when they run across uses that diverge significantly from the mental model they've built up.<p>Functions are a classic example of this. There useful definitions of Functor, Applicative, and Monad for functions, and depending on the mental model you've built up they can be either fairly easy to understand or very difficult to understand. This ends up being a big problem because Applicative and Monadic functions are so pervasive, but they are incomprehensible if your stuck in the traditional data structure mental model. IO is a great example of this- it's really just a specialized State, but it can be really hard to understand how it works if you're thinking about data structures. Parsers are another good example.<p>I generally prefer to start people off with the "monad-as-computation" mental model, roughly "An `m a` is an m-computation that can have side effects and when evaluated returns a value of type a", where Maybe are computations that could fail, Lists are computations that can return multiple times, and IO are computations with all of the normal IO side effects.<p>Starting with IO has the nice benefit that you can also help people come to terms with monadic IO as a means of dealing with lazy evaluation. It's a good gateway both into helping people come to terms with the challenges of lazy IO, and it also helps to provide a concrete motivation for IO in haskell that doesn't result in people going off thinking that Monads are a hammer and every problem in the world is a nail.<p>From there, I think it's helpful to talk not just about bind but also join. Showing someone how to implement join in terms of bind and vice versa is a nice thing to do early because it helps to differentiate Monad from Applicative and it demystifies the "a monad is a monoid in the category of endofunctors" thing a bit (not that I'd proactively bring that up when teaching someone how to use them).<p>I like to characterize the high level difference as something like "Monads are computations that can _call out to_ other computations and integrate their results", "Applicatives can run computations in parallel and combine the resulting structures / side effects", and "Functors allow you to lift pure functions into a computation". At each step, highlighting both how you are getting less powerful (because you can implement functors in terms of applicatives, and applicatives in terms of monads, but not the other way around), and how having less power can help you reason better about your programs (pros/cons of applicative vs. monadic parsers are a good example here).<p>Finally, I think it's important early on to make sure your reader understands higher kinded types. A lot of people are used to languages with generics, but many of those languages aren't expressive enough to let you express something like Functor, and people often lack practice in thinking about something like `Maybe` separately from `Maybe Int` or `Maybe a`.<p>In the end, I think these things really aren't that complicated, but they are built on a different view of programming that a lot of readers have the first time they encounter them, and the best approach isn't to translate the concepts into something people are already familiar with. Instead, I think you need to help the reader adapt their mental model. It's a harder path, but one that I think pays off more in the long run.