
On 16 Dec 2013, at 13:12, Roman Cheplyaka wrote:
* Ivan Lazar Miljenovic
[2013-12-17 00:00:16+1100] On 16 December 2013 22:15, Roman Cheplyaka
wrote: * Herbert Valerio Riedel
[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.