
Every Monad should try to do its best with fail. If, at some point, fail in Monad gets replaced with throwError in MonadError, or with mzero in MonadZero, or with something else, we can ignore fail in Monad, but I would still expect pattern match error via fail to integrate well with at least one of MonadPlus or MonadError.
I respectfully disagree. It is far too easy to use fail in a stack of monad transformers and end up using the wrong instance and getting error "message" semantics; it is far safer to use the appropriate MonadPlus function. fail is a disaster, from both an engineering and theoretical standpoint, and I cannot in good conscious recommend that people use it.
We don't disagree on the current state (my "I would still expect" should be read as "I would like to see", not as "I assume";-). But fixing that state would be another proposal, and one that would need careful design work. Currently, fail is the only program hook into pattern-match failure (for instance, when writing a library for first-class patterns that allows to lift plain Haskell patterns into first-class patterns, or when embedding rewrite rules in Haskell while simply reusing Haskell patterns). So I would prefer not to make the situation any worse by replacing a useable fail with error, as proposed in this thread. Claus