On Sun, Jun 16, 2013 at 02:52:46PM -0700, Gabriel Gonzalez wrote:
> There are three approaches that I'd like to submit for consideration
> and receive feedback on:
>
> * Approach 1: Remove the `Error` constraint from `transformers`
>
> Disadvantage: This silently breaks all existing uses of `fail`. I
> don't know any way to add a compiler warning to notify downstream
> libraries of this change.
I'm in favour of this one. We can catch some of these uses by deprecating
the Error class, as the only predefined instances are for IOException
and String.
I'm going to add another disadvantage of this approach: `ErrorT` is not as good of a name. `EitherT` is a more neutral name, which matters if you want to use it for non-error-based flow control like the way I describe here:
> * Approach 2: Add `EitherT` to `transformers` alongside `ErrorT` and
> have them both implement `MonadError`.
>
> Disadvantage: Bloat from having two almost identical monad
> transformers. However, there is precedent from duplicating
> `StateT`, `WriterT` and `RWST` for both strict and lazy instances.
Those is at least a rationale for two StateT transformers with strict
and lazy instances. (Since the strict WriterT doesn't achieve its aim,
I'm in favour of deprecating it, and the strict RWST.)
The nice thing about Approach 2 is that it is backwards compatible for now and gives downstream libraries a chance to gracefully transition to `EitherT` if you decide to deprecate `ErrorT`. This works out better than usual because the names are different so they can peacefully coexist for one release.
However, you might still want to keep `ErrorT` around as long as `fail` is still part of the `Monad` class.