The real advantage is that we can express the abstraction in the language, which lets us write libraries around it. A single function like fold is much nicer than either having one per type or having to pass in the operation and identity manually:
fold :: (Monoid m, Foldable t) => t m -> m
The fact that monoids are so simple is actually what makes this powerful: fold works for a large set of the types I use day-to-day, whether they're from the base library or specific to my own codebase. There is only a handful of other generic operations that rely on the Monoid class, but that's enough to make the class quite useful. It's a simple abstraction that applies to a lot of different types.
I actually did a count recently; something like 30% of our modules import Data.Monoid. Many of them were just using the (<>) operator, but that's useful in and of itself: no need to define a distinct operator for each of our types that wants one.
It's a simple, incredibly general abstraction that pulls its weight—partly because it doesn't have much to pull.
I actually did a count recently; something like 30% of our modules import Data.Monoid. Many of them were just using the (<>) operator, but that's useful in and of itself: no need to define a distinct operator for each of our types that wants one.
It's a simple, incredibly general abstraction that pulls its weight—partly because it doesn't have much to pull.