Re: Proposal to solve the `EitherT` problem.

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
On Sun, Jun 16, 2013 at 02:52:46PM -0700, Gabriel Gonzalez wrote: 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: http://www.haskellforall.com/2012/07/breaking-from-loop.html
* 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.

On Mon, Jun 17, 2013 at 11:27:18AM -0700, Gabriel Gonzalez wrote:
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 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:
http://www.haskellforall.com/2012/07/breaking-from-loop.html
Fair point, but then EitherT is too neutral, giving no hint of the purpose of the monad instance, and suggesting a symmetry that is absent from the monad: Right is normal monadic sequencing, while Left is the exceptional control path. Things get particularly 'sinister' when you get to naming the throw and catch combinators. It's a bit like the reason for having Writer instead of using the monad instance for (,). So I'd lean more to something like Except, which would also be in line with Moggi's original presentation of this monat and transformer.

On Mon, 17 Jun 2013, Ross Paterson wrote:
On Mon, Jun 17, 2013 at 11:27:18AM -0700, Gabriel Gonzalez wrote:
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 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:
http://www.haskellforall.com/2012/07/breaking-from-loop.html
Fair point, but then EitherT is too neutral, giving no hint of the purpose of the monad instance, and suggesting a symmetry that is absent from the monad: Right is normal monadic sequencing, while Left is the exceptional control path. Things get particularly 'sinister' when you get to naming the throw and catch combinators. It's a bit like the reason for having Writer instead of using the monad instance for (,). So I'd lean more to something like Except, which would also be in line with Moggi's original presentation of this monat and transformer.
I also think that the monad instances on Either and (,) are abuses. (And the monad instance on (->), too, since once I got a hard to find error where a missing argument in a function call was interpreted as an instance of the Reader monad.) Thus I think EitherT is not a good name, and I would also prefer something containing "except".
participants (3)
-
Gabriel Gonzalez
-
Henning Thielemann
-
Ross Paterson