: ( ), Monoid. Maybe, , . :
import Data.Monoid (Monoid, mempty, mappend)
import qualified Data.Foldable as F
-- Either we have a maximum value, or Nothing, if the
-- set of values is empty.
newtype Maximum a = Maximum { getMaximum :: Maybe a }
deriving (Eq, Ord, Read, Show)
instance Ord a => Monoid (Maximum a) where
mempty = Maximum Nothing
-- If one part is Nothing, just take the other one.
-- If both have a value, take their maximum.
(Maximum Nothing) `mappend` y = y
x `mappend` (Maximum Nothing) = x
(Maximum (Just x)) `mappend` (Maximum (Just y))
= Maximum (Just $ x `max` y)
maximum' :: (F.Foldable t, Ord a) => t a -> Maximum a
maximum' = F.foldMap (Maximum . Just)