Proposal: merge either into transformers

Edward Kmett ekmett at
Fri Dec 7 19:01:52 CET 2012

On Fri, Dec 7, 2012 at 12:45 PM, Ross Paterson <ross at> wrote:

> On Fri, Dec 07, 2012 at 09:44:27AM +0000, Roman Cheplyaka wrote:
> > I propose to add the sole module of the 'either' package[1],
> > Control.Monad.Trans.Either, to the transformers package.
> >
> > It provides EitherT, a very basic and fundamental data type. The
> > difference between EitherT and ErrorT is that the latter has an Error
> > constraint, which is used to imlement 'fail'.
> >
> > Note that 'either' depends on the 'semigroupoids' and 'semigroup'
> > packages to provide appropriate instances. The proposal is not to add
> > those instances to 'transformers' to avoid additional dependencies. The
> > instances can then be left in the 'either' package or moved to the
> > 'semigroupoids' and 'semigroup' packages respectively. ('semigroupoids'
> > already depends on 'transformers', while 'semigroups' does not).
> Orphan instances are to be avoided, so moving the instances to those
> packages seems the only option.

Sure. I'd be happy to invert the dependencies. As I wrote semigroups,
semigroupoids and either in the first place. ;)

> > Compared to the 'either' package, Show, Read, Eq and Ord instances will
> > be dropped to keep the code Haskell2010 (those instances require
> > FlexibleInstances, FlexibleContexts, and UndecidableInstances).
> That's true.  Some other points:
> The either package has mapEitherT as the binary map
>   mapEitherT :: Functor m => (e -> f) -> (a -> b) -> EitherT e m a ->
> EitherT f m b
> but consistency with the rest of transformers would apply this name to
>   mapEitherT :: (m (Either e a) -> n (Either e' b)) -> EitherT e m a ->
> EitherT e' n b
>   mapEitherT f m = EitherT $ f (runEitherT m)

Something that provides the existing 'mapEitherT' functionality would be
nice to retain as it gets used in multiple packages. Perhaps bikeshed it to
'bimapEitherT', and use 'mapEitherT' for your notion?

> (The binary map can't be recovered using Bifunctor because of the argument
> order.)
> either has
>   hoistEither :: Monad m => Either e a -> EitherT e m a
> Maybe transformers should have similar functions for all the other monad
> transformers.

+1 I would really like this.

left and right are used with different meanings in Control.Arrow
> (surmountable with qualification, of course).  I see that the idea
> is to be symmetrical, but the monad structure is asymmetric.

I'm not wedded to the names of the 'left' and 'right' combinators in

The functionality would be nice to retain, but the names I'm completely
indifferent to.

> Would we want a catch function?

It probably wouldn't hurt.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the Libraries mailing list