Good writeup. Haskell actually does have an Error type class and ErrorT monad transformer for more fine-grained error handling.
Maybe gives you binary error handling, it either fails (Nothing) or succeeds (Just).
Either gives you "stringly-typed" errors which is sometimes a good choice.
http://hackage.haskell.org/packages/archive/mtl/1.1.0.2/doc/...