
The thing that I found hardest to understand about monads is that they are used to obtain very special consequences (fitting things like I/O and updatable arrays into a functional language) without actually involving any special machinery. Whenever you look for the magic, it's nowhere. But it's happening none the less. It's really the monad laws that matter; they express _just_ enough of the informal notion of doing things one after the other to be useful for side-effective things that need to be done one after the other without expressing so much that they preclude informally pure things like lists and maybes. There's a thing I'm still finding extremely hard about monads, and that's how to get into the frame of mind where inventing things like Monad and Applicative and Arrows is something I could do myself. Functor, yes, I could have invented Functor. But not the others.