At ICFP, Simon mentioned a willingness to revisit the placement of fail in Monad for GHC, offering to defer to the core libraries committee on the issue.

I'm somewhat loathe to do anything about this for 7.10, as I'd like to focus on changes that can be made without requiring #ifdef's in user code for the next major release, and just focus on making progress on things that are near universally accepted to be good ideas, and which can be "defended against" without CPP. e.g. finally bringing in Applicative as a superclass of Monad.

That said, for say, 7.12 a well-reasoned proposal for what to do with fail would have a very high likelihood of getting through! (for example, exiling it to a MonadFail class or to the existing MonadPlus) Especially as if the split-base proposal goes through for 7.12 a lot of breaking changes would already be in the air.

-Edward


On Mon, Dec 16, 2013 at 9:17 AM, Malcolm Wallace <malcolm.wallace@me.com> wrote:

On 16 Dec 2013, at 13:12, Roman Cheplyaka wrote:

> * Ivan Lazar Miljenovic <ivan.miljenovic@gmail.com> [2013-12-17 00:00:16+1100]
>> On 16 December 2013 22:15, Roman Cheplyaka <roma@ro-che.info> wrote:
>>> * Herbert Valerio Riedel <hvr@gnu.org> [2013-12-16 10:53:21+0100]
>>>> Why not simply use the existing `fail :: String -> IO a` method instead?
>>>
>>> The purpose of 'fail' is to handle monadic pattern-match failures.
>>> I consider explicit use of 'fail' in user code a hack.
>>
>> Or for use with parser-combinator libraries (though I suppose this
>> could be seen as a pattern-match failure...)?
>
> I'd consider that an abuse, too. E.g. Parsec provides a parserFail
> function that you can call instead.

I respectfully disagree.  Whilst it was probably a mistake originally to include "fail" as a method of the Monad class, it has always been a useful additional method.  Personally, I would have it in a separate class (called MonadFail, or similar).  But wherever it lives, we would always have had it.

I see no good reason to distinguish between runtime pattern-match failure, and a direct user call of "fail".  It is quite common to write parsers using pattern-matching, and why should one kind of backtracking be privileged over another?  Their effects are of exactly the same kind.

e.g.

    keyword = ( do "let" <- word -- fails if the string does not match
                   b <- binding
                   return (LET b) )
               `onFail`
              ( do "case" <- word
                   exp   <- expression
                   "of"  <- word `onFail` fail "missing keyword 'of'"
                   alts  <- many1 alternative
                   return (CASE exp alts) )

etc.

_______________________________________________
Libraries mailing list
Libraries@haskell.org
http://www.haskell.org/mailman/listinfo/libraries