I was trying to avoid offering up color swatches for the bikeshed, but here are my thoughts:<br><br>The use-cases that most often arise are that you either want to:<br><br>1.) take the Min or Max of a common Bounded type. These have a nice analogues in Sum and Product in Data.Monoid now.<br>
<br>2.) take the Min or Max of an unbounded Type, and therefore need to have a unit added. These have nice analogues in First and Last in the Data.Monoid now, and reflect the practice of using the equivalent of Maybe to transform something that is notionally a Semigroup into a Monoid. This is common for things like priority queues. In fact, using a fingertree as a fair priority queue is really easy with this monoid. In Data.Monoid.Ord from the monoids package these are &quot;MinPriority&quot; and &quot;MaxPriority&quot; for that reason. Note that by adding just a minimum or maximum element these aren&#39;t strong enough to be Bounded, and this is the minimum requirement to really be able to implement a priority queue with any Ord&#39;ered value as the priority, while handling the empty queue case gracefully.<br>
<br>On the other hand, composing AddBounds introduces another element on the other side, which serves as an annihilator when composed with Min and Max. This is fine for some applications, but I don&#39;t believe it subsumes MinPriority and MaxPriority.<br>
<br>AddBounds is a useful type, but I don&#39;t think injecting MinPriority a/MaxPriority a into the larger Max (AddBounds a) and Min (AddBounds a) is the right solution.<br><br>By that same &#39;the type is too large&#39; token, I don&#39;t like just providing MinPriority/MaxPriority, since Min and Max are perfectly usable and much more efficient monoids with a smaller domain.<br>
<br>So in my perfect world the patch would include Min/Max/MinPriority/MaxPriority and another proposal could find a nice place to shoehorn AddBounds. ;)<br><br>-Edward Kmett<br><br><div class="gmail_quote">On Thu, Sep 23, 2010 at 2:25 PM, Conal Elliott <span dir="ltr">&lt;<a href="mailto:conal@conal.net">conal@conal.net</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">I encountered exactly this issue in my use of the Max &amp; Min monoids in Reactive.  I wanted to allow already-bounded types to use their own minBound for Max and maxBound for Min, and also allow unbounded types to be used.  So, rather than entangling bound addition with Max &amp; Min, I defined AddBounds type wrapper, which is *orthogonal* to Max &amp; Min.  If your type is already Bounded, then use my simple Max &amp; Min wrappers directly.  If not (as in Reactive&#39;s use), compose Max or Min with AddBounds.<br>


<br>I&#39;m sorry I didn&#39;t think to mention this useful composition the Max &amp; Min trac ticket.<br><font color="#888888"><br>   - Conal</font><div><div></div><div class="h5"><br><br><div class="gmail_quote">On Thu, Sep 23, 2010 at 10:47 AM, Gregory Collins <span dir="ltr">&lt;<a href="mailto:greg@gregorycollins.net" target="_blank">greg@gregorycollins.net</a>&gt;</span> wrote:<br>


<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div>Felipe Lessa &lt;<a href="mailto:felipe.lessa@gmail.com" target="_blank">felipe.lessa@gmail.com</a>&gt; writes:<br>



&gt; On Thu, Sep 23, 2010 at 12:58 PM, Jake McArthur &lt;<a href="mailto:jake.mcarthur@gmail.com" target="_blank">jake.mcarthur@gmail.com</a>&gt; wrote:<br>
&gt;<br>
</div><div>&gt;&gt;&gt;    -- | Ordered monoid under &#39;max&#39;.<br>
&gt;&gt;&gt;    newtype Max a = Max { getMax :: a }<br>
&gt;&gt;&gt;            deriving (Eq, Ord, Read, Show, Bounded)<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;    instance (Ord a, Bounded a) =&gt; Monoid (Max a) where<br>
&gt;&gt;&gt;            mempty = Max minBound<br>
&gt;&gt;&gt;            Max a `mappend` Max b = Max (a `max` b)<br>
&gt;<br>
&gt; Why should we prefer this monoid over<br>
&gt;<br>
&gt;&gt; data Max a = Minimum | Max a<br>
&gt;&gt;              deriving (Eq, Ord, Read, Show)<br>
&gt;&gt;<br>
&gt;&gt; instance Ord a =&gt; Monoid (Max a) where<br>
&gt;&gt;   mempty = Minimum<br>
&gt;&gt;   Minimum `mappend` x   = x<br>
&gt;&gt;   x `mappend` Minimum   = x<br>
&gt;&gt;   Max a `mappend` Max b = Max (a `max` b)<br>
<br>
</div>You&#39;re right, the original wouldn&#39;t fly because there are unbounded<br>
types (like Integer) that you&#39;d like to be able to use with Max/Min.<br>
<br>
Rather than your proposal I would suggest that Max/Min mirror<br>
the existing First/Last, namely:<br>
<br>
    newtype Max a = Max { getMax :: Maybe a }<br>
<div>      deriving (Eq, Ord, Read, Show)<br>
<br>
    instance (Ord a) =&gt; Monoid (Max a) where<br>
</div>        mempty  = Max Nothing<br>
        mappend = max<br>
<br>
G<br>
<font color="#888888">--<br>
Gregory Collins &lt;<a href="mailto:greg@gregorycollins.net" target="_blank">greg@gregorycollins.net</a>&gt;<br>
</font><div><div></div><div>_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank">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></div><br>_______________________________________________<br>
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>
<br></blockquote></div><br>