I often explain monads to laypeople as "It's a way to abstract away extra information that's passed through the computation, and define arbitrary ways to handle that information." One of the possible types of "extra information" that may be attached are the types of exceptions thrown: see the Error monad.
And yeah, monads have most of the same problems that checked exceptions do. Each action in the monad must have the same type; you can't just ignore one of those bits of extra information and declare that it doesn't matter in this context. For example, if your complicated algorithm writes to a log file, you probably don't care in the rest of the program and could just as easily treat it as pure. But the type system won't let you, unless you fall back on cheats like unsafePerformIO.
I dunno really what the right answer for this is, but I really like the Erlang philosophy toward errors. "Let it crash, then do something simpler." Instead of trying to enumerate all the ways your program can fail, it just assumes that you will fail sometimes, so you ought to try multiple ways to succeed instead. That requires quite a paradigm shift from the way programmers normally think about programming, though.