While I personally prefer the (:*:) and (:+:) notation, both require an additional extension, TypeOperators, and to Ross&#39;s point (:+:) fails to be an Applicative/Monad transformers, so the scope of the package starts to stretch there.<div>
<br></div><div>That said, there are always ideal monad coproducts, but then you need the notion of ideal monads. ;)</div><div><br></div><div>data Ideal m a = Return a | Ideal (m a)</div><div>data Mutual m n a = Mutual (m (Mutual n m a))</div>
<div>data (m :+: n) a = Coproduct { runCoproduct :: Either (m a) (n a) }</div><div>type IdealCoproduct m n = Ideal (Mutual m n :+: Mutual n m)</div><div><br></div><div>given a definition for</div><div><br></div><div>class MonadIdeal m where</div>
<div>    idealize :: m (Ideal m a) -&gt; m a</div><div><br></div><div>which describes a monad, that has a separate return.</div><div><br></div><div>You can define</div><div><br></div><div>instance MonadIdeal m =&gt; Monad (Ideal m)</div>
<div><br></div><div>and then you can define an &#39;ideal monad coproduct&#39; of any two ideal monads from there.</div><div><br></div><div>This covers, Maybe, Either, Identity, and a bunch of others. wherever the &#39;Return&#39; constructor can be cleanly separated from the rest of the monad.</div>
<div><br></div><div>However, this drifts out of library/platform territory and into esoterica.</div><div><br></div><div>-Edward Kmett</div><div><br><div class="gmail_quote">On Mon, Mar 29, 2010 at 5:42 AM, Nicolas Pouillard <span dir="ltr">&lt;<a href="mailto:nicolas.pouillard@gmail.com">nicolas.pouillard@gmail.com</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, 26 Mar 2010 19:28:18 +0000, Ross Paterson &lt;<a href="mailto:ross@soi.city.ac.uk">ross@soi.city.ac.uk</a>&gt; wrote:<br>

&gt; On Fri, Mar 26, 2010 at 05:24:18AM -0700, Nicolas Pouillard wrote:<br>
&gt; &gt; Could we have functors products, sums, fixpoints as well? It would really<br>
&gt; &gt; avoid to redefine them each time.<br>
&gt;<br>
&gt; Do you mean<br>
&gt;<br>
&gt;   data Product f g a = Product (f a) (g a)<br>
<br>
</div>Yes, I was thinking of using :*: instead of Product:<br>
<br>
data (:*:) f g a = (:*:) (f a) (g a)<br>
<div class="im"><br>
&gt; with Functor, Foldable, Traversable and Applicative instances?<br>
<br>
</div>Yes.<br>
<div class="im"><br>
&gt; Not sure if the other two count as transformers.<br>
<br>
</div>Why not:<br>
<br>
data (:+:) f g a = Inl (f a) | Inr (g a)<br>
<br>
  And sure, no applicative nor monad instance for this one.<br>
<br>
And Fix like in category-extras:<br>
<a href="http://hackage.haskell.org/packages/archive/category-extras/0.53.5/doc/html/Control-Functor-Fix.html" target="_blank">http://hackage.haskell.org/packages/archive/category-extras/0.53.5/doc/html/Control-Functor-Fix.html</a><br>

<br>
Best regards,<br>
<div class="im"><br>
--<br>
Nicolas Pouillard<br>
<a href="http://nicolaspouillard.fr" target="_blank">http://nicolaspouillard.fr</a><br>
_______________________________________________<br>
</div><div><div></div><div class="h5">Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org">Libraries@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/libraries" target="_blank">http://www.haskell.org/mailman/listinfo/libraries</a><br>
</div></div></blockquote></div><br></div>