Take a look at this stuff in your favorite flavor of the Blub programming language. Most of the same stuff that the Haskell community calls with strange names exists in the imperative/OO world. However, in the imperative/OO world these things tend to be ad-hoc constructions ("design patterns"?) that don't have any theoretical background and are difficult to reason about.
I'm finding more and more that the hardest part of haskell is understanding the syntax and the terminology.
Take the IO Monad. Everyone who wrote some web/servlet code, that needs to output stuff to the web over several classes (might not be the best design in the beginning) uses a Writer (or other class) to aggregate output. He therefore, as global vars are bad (and thread local are worse ;-) adds a Writer to every method.
public T doSomeStuff(T input, Writer io)
This is nasty and ugly, and the IO monad is in essence just another way to write this in a neat form, make it composable and control the IO environment.
public IO<T> doSomeStuff(IO<T> input)
But you would not get this insight from any of the monad tutorials written by Haskell people (except the link above).
Simple monad insight comes form other people outside the Haskell community, e.g. James Iry