On Wed, Mar 25, 2026 at 02:47:35PM +0000, Tom Ellis wrote:
What Olaf seems to have in mind does neet a Monoid, for example:
Yes, I misunderstood the type `Data.Semigroup.Max` (which just happens to live in `Data.Semigroup`) for the `Semigroup` class. I missed that the class is actually `Monoid`.
Mind you there's a conflict between the suggested `foldMap'` implementation for Bounded elements and efficient implementations with ordered Foldable collections (Map, IntMap, Set, ...). The latter, just return quickly return the least or greatest element without paying a linear cost to perform the proposed fold. So in practice, in code that is polymorphic in the container type, it is better to define: minimumMaybe :: (Ord a, Foldable t) => t a -> Maybe a minimumMaybe (null -> True) = Nothing minimumMaybe xs = Just $! minimum xs maximumMaybe :: (Bounded a, Ord a, Foldable t) => t a -> a maximumMaybe (null -> True) = Nothing maximumMaybe xs = Just $! maximum xs and these can then be leveraged to yield: boundedMinimum :: (Bounded a, Ord a, Foldable t) => t a -> a boundedMinimum (minimumMaybe -> Just a) = a boundedMinimum _ = maxBound boundedMaximum :: (Bounded a, Ord a, Foldable t) => t a -> a boundedMaximum (maximumMaybe -> Just a) = a boundedMaximum _ = minBound and variants for semi-lattices, e.g. natMaximum :: Foldable t => t Natural -> Natural natMaximum (maximumMaybe -> Just n) = n natMaximum _ = 0 -- Viktor. 🇺🇦 Слава Україні!