<div> Wed, Jul 1, 2009 at 4:17 PM, Raynor Vliegendhart <span dir="ltr">&lt;<a href="mailto:shinnonoir@gmail.com" target="_blank">shinnonoir@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">We could use (Control.Category..) as an operator, but this would<br>require an additional wrapping layer if we wish to use the existing<br>
Monoid instances:<br><br>&gt; import Prelude hiding (id, (.))<br>&gt; import Control.Category<br>&gt; import Data.Monoid<br>&gt;<br>&gt; -- Category wrapper for existing Monoid instances<br>&gt; newtype MonoidC m a b = MonoidC {unwrapMC :: m} deriving (Show)<br>
&gt;<br>&gt; instance Monoid m =&gt; Category (MonoidC m) where<br>&gt;     id = MonoidC mempty<br>&gt;     MonoidC m . MonoidC n = MonoidC $ m `mappend` n<br><br>Furthermore, writing Category instances for monoids require dummy type<br>
parameters:<br><br>&gt; -- Example instance<br>&gt; newtype SumC m a b = SumC {getSumC :: m} deriving (Show, Eq)<br>&gt;<br>&gt; instance Num a =&gt; Category (SumC a) where<br>&gt;     id = SumC (fromIntegral 0)<br>&gt;     SumC x . SumC y = SumC $ x + y<br>
</blockquote></div>
<div>I have a monoid-as-category and category-endomorphism as monoid in:</div>
<div><a href="http://comonad.com/haskell/monoids/dist/doc/html/monoids/Data-Monoid-Categorical.html" target="_blank">http://comonad.com/haskell/monoids/dist/doc/html/monoids/Data-Monoid-Categorical.html</a></div>
<div> </div>
<div>but there are issues.</div>
<div> </div>
<div>1.)  these completely change the typing involved</div>
<div>2.) the monoid as category-with-one-object is pretty scary to someone without a category theory background. </div>
<div>3.) This doesn&#39;t properly represent the category-with-one-object because at best the two phantom types yield you something like a category like Hask, which has been fully connected * M where M is the category of your monoid. Even if you use GADTs to cut down the phantom types to one where the head and tail of the arrow are the same object and |.| takes a category to its discrete category (discarding all non-identity arrows) you are looking at a category like |Hask| * M because of the phantom type. </div>

<div> </div>
<div><span>data</span> <span>CMonoid</span> <span>m</span> <span>n</span> <span>o</span> <span>where</span><br><a name="12238310625d53aa_line-38"></a>    <span>M</span> <span>::</span> <span>Monoid</span> <span>m</span> <span>=&gt;</span> <span>m</span> <span>-&gt;</span> <span>CMonoid</span> <span>m</span> <span>a</span> <span>a</span></div>

<div><span></span> </div>
<div><span><span>instance</span> <span>Monoid</span> <span>m</span> <span>=&gt;</span> <span>Category</span> <span>(</span><span>CMonoid</span> <span>m</span><span>)</span> <span>where</span><br><a name="12238310625d53aa_line-51"></a>    <span>id</span> <span>=</span> <span>M</span> <span>mempty</span><br>
<a name="12238310625d53aa_line-52"></a>    <span>M</span> <span>a</span> <span>.</span> <span>M</span> <span>b</span> <span>=</span> <span>M</span> <span>(</span><span>a</span> <span>`mappend`</span> <span>b</span><span>)</span><br>
</span></div>
<div><span></span> </div>
<div>
<div>Attempting to go any further and railroad that type to equal m fails when you go to define id. So the categorical notion of a monoid is pretty much a non-starter in Haskell.</div>
<div> </div></div>
<div><span></span></div>
<div>-Edward Kmett<br><br></div>
<div class="gmail_quote">On<br>Another disadvantage of this approach is that we cannot have a default<br>monoid instance for lists (kind mismatch).</div>