MonadFail proposal (MFP): Moving fail out of Monad
Henning Thielemann
lemming at henning-thielemann.de
Tue Jun 9 21:56:59 UTC 2015
now some details to the discussion:
On Tue, 9 Jun 2015, David Luposchainsky wrote:
> https://github.com/quchen/articles/blob/master/monad_fail.md
>
> Here's a short abstract:
>
> - - Move `fail` from `Monad` into a new class `MonadFail`.
You think about making MonadFail a subclass of Applicative where the name
MonadFail becomes misleading - how about naming it Fail instead?
> - - Remove the `String` argument? **No.** The `String` might help error reporting
> and debugging. `String` may be ugly, but it's the de facto standard for
> simple text in GHC. No high performance string operations are to be
> expected with `fail`, so this breaking change would in no way be justified.
> Also note that explicit `fail` calls would break if we removed the argument.
You know that I am concerned with a strict separation of programming
errors and exceptions. "fail" is part of the confusion between the two
concepts. If "fail" is inserted by the compiler as desugaring of a pattern
match then it gets a compiler generated string as argument. This string
refers to program details like source locations and constructor names that
have no meaning for the program user. They are intended for debugging,
they address the programmer. This implies that "fail" indicates a
programming error. In contrast to that, in a monad like Maybe we want to
convert a mismatching pattern to Nothing. The compiler generated argument
to "fail" does not show up in the Nothing result. This usecase is clearly
not for debugging but for regular use in a program. We only want to get
the exceptional value Nothing.
We should clearly decide what "fail" is intended for - for programming
errors or for exceptions. I guess that people want to use it in the second
sense, e.g. something like "guard" driven by a pattern match in the Maybe
or list monad. But then "fail" must not have an argument because what user
related information can the compiler add automatically? Instead of
removing the String argument from "fail", the compiler could simply call
"mzero" instead. If we want to use "fail" for exceptions then it would be
also ok for parser libraries to use it for parser failures. Nonetheless
they might be better served with an Except-like monad where they can
choose more specific types for the exception messages, e.g. parser errors
with source location. In summary I think that the cleanest solution would
be to phase out "fail" completely in the long run. But using "mzero"
instead of "fail" for monadic pattern matches would alter the proposal
considerably. Using "mzero" requires a monad with "mplus" and for support
of monads with "mzero" but no "mplus" we need to split MonadPlus, too.
More information about the Libraries
mailing list