
On Mon, 2011-11-28 at 20:47 +0100, Bas van Dijk wrote:
On 28 November 2011 20:22, Jake McArthur
wrote: I'd just like to add one further remark. If we had a separate MonadFail class then we could get back the original behavior by imposing an Error constraint on it, but without the problems we get by imposing it on the Monad instance instead.
The problem with a separate MonadFail class is when to add that constraint to the type of a do-expression.
Currently do-expression with a bind:
do {p <- e; stmts}
are translated to:
let ok p = do {stmts} ok _ = fail "..." in e >>= ok
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.
It may be just me but I always desugared in head do {p <- e; stmts} => e >>= \p -> do {stmts} Hence I would prefer the option 1) with special syntax for MonadFail: do {p - e; stmts} => e >>= \p' -> case p' of p -> do {stmts}; _ -> fail "..."
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.
To me 2, 3 and 4 seem fishy. I like 1 a lot but I'm unsure how many programs will break because of it.
From me +1 for 1) with the same note.
Regards,
Bas
Regards