<br><div class="gmail_quote">On Fri, Dec 7, 2012 at 12:45 PM, Ross Paterson <span dir="ltr">&lt;<a href="mailto:ross@soi.city.ac.uk" target="_blank">ross@soi.city.ac.uk</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On Fri, Dec 07, 2012 at 09:44:27AM +0000, Roman Cheplyaka wrote:<br>
&gt; I propose to add the sole module of the &#39;either&#39; package[1],<br>
&gt; Control.Monad.Trans.Either, to the transformers package.<br>
&gt;<br>
&gt; It provides EitherT, a very basic and fundamental data type. The<br>
&gt; difference between EitherT and ErrorT is that the latter has an Error<br>
&gt; constraint, which is used to imlement &#39;fail&#39;.<br>
&gt;<br>
&gt; Note that &#39;either&#39; depends on the &#39;semigroupoids&#39; and &#39;semigroup&#39;<br>
&gt; packages to provide appropriate instances. The proposal is not to add<br>
&gt; those instances to &#39;transformers&#39; to avoid additional dependencies. The<br>
&gt; instances can then be left in the &#39;either&#39; package or moved to the<br>
&gt; &#39;semigroupoids&#39; and &#39;semigroup&#39; packages respectively. (&#39;semigroupoids&#39;<br>
&gt; already depends on &#39;transformers&#39;, while &#39;semigroups&#39; does not).<br>
<br>
</div>Orphan instances are to be avoided, so moving the instances to those<br>
packages seems the only option.</blockquote><div><br></div><div>Sure. I&#39;d be happy to invert the dependencies. As I wrote semigroups, </div><div>semigroupoids and either in the first place. ;)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">
&gt; Compared to the &#39;either&#39; package, Show, Read, Eq and Ord instances will<br>
&gt; be dropped to keep the code Haskell2010 (those instances require<br>
&gt; FlexibleInstances, FlexibleContexts, and UndecidableInstances).<br>
<br>
</div>That&#39;s true.  Some other points:<br>
<br>
The either package has mapEitherT as the binary map<br>
<br>
  mapEitherT :: Functor m =&gt; (e -&gt; f) -&gt; (a -&gt; b) -&gt; EitherT e m a -&gt; EitherT f m b<br>
<br>
but consistency with the rest of transformers would apply this name to<br>
<br>
  mapEitherT :: (m (Either e a) -&gt; n (Either e&#39; b)) -&gt; EitherT e m a -&gt; EitherT e&#39; n b<br>
  mapEitherT f m = EitherT $ f (runEitherT m)<br></blockquote><div> </div><div>Something that provides the existing &#39;mapEitherT&#39; functionality would be nice to retain as it gets used in multiple packages. Perhaps bikeshed it to &#39;bimapEitherT&#39;, and use &#39;mapEitherT&#39; for your notion?</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
(The binary map can&#39;t be recovered using Bifunctor because of the argument<br>
order.)<br>
<br>
either has<br>
<br>
  hoistEither :: Monad m =&gt; Either e a -&gt; EitherT e m a<br>
<br>
Maybe transformers should have similar functions for all the other monad<br>
transformers.<br></blockquote><div><br></div><div>+1 I would really like this. </div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
left and right are used with different meanings in Control.Arrow<br>
(surmountable with qualification, of course).  I see that the idea<br>
is to be symmetrical, but the monad structure is asymmetric.<br></blockquote><div><br></div><div>I&#39;m not wedded to the names of the &#39;left&#39; and &#39;right&#39; combinators in &#39;either&#39;. </div><div><br></div>
<div>The functionality would be nice to retain, but the names I&#39;m completely indifferent to.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Would we want a catch function?</blockquote><div><br></div><div>It probably wouldn&#39;t hurt.</div><div> </div><div>-Edward</div></div>