# Maximum and Minimum monoids

Greg Fitzgerald garious at gmail.com
Thu Dec 27 21:02:21 CET 2012

```> It made sense in my specific use case, but I think Gabriel's version is
better as the general approach.

Can Gabriel derive his version from Michael's with:

instance Bounded (Maybe a) where
maxBound = Nothing
minBound = Nothing

The Bounded constraint seems right to me.  If Bounded doesn't apply to your
datatype, maybe a Semigroup would be more appropriate than a Monoid?

Thanks,
Greg

On Thu, Dec 27, 2012 at 11:07 AM, Michael Snoyman <michael at snoyman.com>wrote:

>
>
>
> On Thu, Dec 27, 2012 at 8:45 PM, Gabriel Gonzalez <gabriel439 at gmail.com>wrote:
>
>> I don't know if this has been brought up before or not, but would it be
>> possible to add the Maximum and Minimum monoids to Data.Monoid?  The
>> following implementations extend the traditional semigroups using Maybe.
>>
>> ******
>>
>> newtype Maximum a = Maximum { getMaximum :: Maybe a }
>>
>> instance (Ord a) => Monoid (Maximum a) where
>>     mempty = Maximum Nothing
>>
>>     mappend (Maximum Nothing) m2 = m2
>>     mappend m1 (Maximum Nothing) = m1
>>     mappend (Maximum (Just a1)) (Maximum (Just a2)) = Maximum (Just (max
>> a1 a2))
>>
>> newtype Minimum a = Minimum { getMinimum :: Maybe a }
>>
>> instance (Ord a) => Monoid (Minimum a) where
>>     mempty = Minimum Nothing
>>
>>     mappend (Minimum Nothing) m2 = m2
>>     mappend m1 (Minimum Nothing) = m1
>>     mappend (Minimum (Just a1)) (Minimum (Just a2)) = Minimum (Just (min
>> a1 a2))
>>
>> ******
>>
>> These also give the correct behavior when folding empty structures by
>> returning Nothing.
>>
>> The reason I'm asking is that my `pipes` library uses `WriterT` to
>> implement folds and having the above monoids lets me implement minimum and
>> maximum folds elegantly.  I can always provide these monoids myself, but I
>> feel like they belong in Data.Monoid.
>>
>>
> +1, I've had to implement at least one of these in the past. In my case, I
> think I ended up doing it something like:
>
> newtype Maximum a = Maximum { getMaximum :: a }
> instance (Ord a, Bounded a) => Monoid (Maximum a) where
>     mempty = Maximum minBound
>     mappend (Maximum x) (Maximum y) = Maximum (max x y)
>
> It made sense in my specific use case, but I think Gabriel's version is
> better as the general approach.
>
> Michael
>
> _______________________________________________
> Libraries mailing list