
This proposal [1] was originally submitted to Trac by Conal Elliott, but it was apparently abandoned and closed after some time. I've picked it back up and written out a patch. Here is the text of the proposal (including a correction mentioned in the first comment on the ticket):
I'd like to add two instances to Data.Monoid, alongside of All/Any, Sum/Product, and First/Last.
Here's a current instance (as a style example):
-- | Boolean monoid under conjunction. newtype All = All { getAll :: Bool } deriving (Eq, Ord, Read, Show, Bounded)
instance Monoid All where mempty = All True All x `mappend` All y = All (x && y)
My proposed addition:
-- | Ordered monoid under 'max'. newtype Max a = Max { getMax :: a } deriving (Eq, Ord, Read, Show, Bounded)
instance (Ord a, Bounded a) => Monoid (Max a) where mempty = Max minBound Max a `mappend` Max b = Max (a `max` b)
-- | Ordered monoid under 'min'. newtype Min a = Min { getMin :: a } deriving (Eq, Ord, Read, Show, Bounded)
instance (Ord a, Bounded a) => Monoid (Min a) where mempty = Min maxBound Min a `mappend` Min b = Min (a `min` b)
I have a niggling uncertainty about the Ord & Bounded instances for Min a? Is there a reason flip the a ordering instead of preserving it?