On Fri, Dec 20, 2013 at 6:27 PM, Ganesh Sittampalam <ganesh@earth.li> wrote:
On 16/12/2013 16:50, Herbert Valerio Riedel wrote:
> On 2013-12-16 at 14:54:53 +0100, Andreas Abel wrote:
>> On 16.12.2013 14:12, Roman Cheplyaka wrote:
>>>>> The purpose of 'fail' is to handle monadic pattern-match failures.
>>>>> I consider explicit use of 'fail' in user code a hack.
>>>
>>> I treat 'fail' as a semi-private method of the Monad class. I may
>>> override it, but I should never call it. It only exists for the
>>> compiler.
>>
>> This is useful information.  Please add it to the documentation.  That
>> would definitely help newcomers to get some orientation in the design
>> space of exceptions...
>
> [...]
>
> If this is really the intent of `fail`, shouldn't we then also attach a
>
>   {-# WARNING fail "Monad(fail) is not supposed to be called directly" #-}
>
> to the `fail` method definition to help catch illegal uses of `fail` in
> user code?
>
> (Fwiw, I've tested attaching such a warning to `fail` in GHC HEAD's
> libraries/base/GHC/Base.lhs and it seems to work just fine so far... so
> if there's consensus, we could add that for GHC 7.8)

I'm not sure I follow the logic of this. If it does continue to exist,
what are the arguments against using it explicitly?

Cheers,

Ganesh

Some monads have no sensible implementation for fail, so therefore, `fail` can't be bound by any laws besides what's in the type. So when you're writing common functions involving error handling, the type of `fail` gives you some requirements on how to use it, but you get no promise that it does something useful (note: `fail = error` is not useful).

However, when you use something like MonadError, you're guaranteed (by the type) that you can use throwError, and promised (by those who create instances for MonadError) that it will have a useful meaning.

(And this is just one of the reasons.)

Regards,
Stijn