
With a separate MonadFail class we have 4 options:
1) Simply translate to: "e >>= \p -> do{stmts}" instead. This means pattern match errors are always turned into errors.
2) Give all do-expressions a MonadFail constraint.
3) Only give do-expressions with pattern bindings a MonadFail constraint.
4) Only give do-expressions with pattern bindings with uncomplete patterns a MonadFail constraint.
I'm sure this has been brought up in the many 'fail' discussions that have occurred, but what about MonadPlus and substituting a refuted pattern match with mzero? The only time I've used refutable pattern matches is in a list or parser where something like "'a' <- Parse.char" is convenient. What about pattern matches desugaring as something like tmp <- Parse.char case tmp of 'a' -> { ... rest of do block ... } _ -> mzero Of course that just replaces MonadFail with MonadPlus and how to decide if the extra constraint is needed is still unsolved, but at least it's an already existing class. I originally wanted to ask for uses of 'fail', because I haven't heard of any of those, but then I thought of how I use refutable pattern matches. And then that made me think the way fail takes a String is awkward and weird and none of my refutable matches make use of that fact. Then that made me think reusing MonadPlus's mzero seemed more appropriate.