IOモナドのような副作用系のモナドは、

1. Stateモナドを一回写経
2. loop :: Monad m => Int -> m a -> m a とか、when :: Monad m => Bool -> m a -> m aのような
  『モナドをとってモナドを返す』関数をいろいろ作り、Stateモナド内では何が起きているのかを考える
3. 全部消してStateモナドを記憶を頼りに再実装

ってやればかなり理解できる。

Listモナドは、リスト内包表現をListモナドで表現するのを繰り返していれば、分かってくる。
Maybeモナドはその劣化版。

これらはすべて一本道の逐次計算あるいは逐次実行、すなわちモナドが抽象化しているものの具体例になるんだけど、
そこまで行く前に、StateモナドとListモナドを別々に理解して、いつでもモナドのインスタンスとして再実装できるようになるほうが、
数学者でなければ結局は早いと思う。

いずれ、Listモナドは量子ピタゴラススイッチなのだと理解できる日が来よう。