When looking at Data.Monoid, I see there are various newtype wrappers, such as All, Sum, or Product, which e
How about in an instance like this:
myData :: [(Sum Integer, Product Double)]
myData = zip (map Sum [1..100]) (map Product [0.01,0.02..])
main = print $ mconcat myData
Or without the newtype wrapper and the Monoid instance:
myData :: [(Integer, Double)]
myData = zip [1..100] [0.01,0.02..]
main = print $ foldr (\(i, d) (accI, accD) -> (i + accI, d * accD)) (0, 1) myData
This is due to the fact that (Monoid a, Monoid b) => Monoid (a, b). Now, what if you had custom data types and you wanted to fold over a tuple of these values applying a binary operation? You could simply write a newtype wrapper and make it an instance of Monoid with that operation, construct your list of tuples, then just use mconcat to fold across them. There are many other functions that work on Monoids as well, not just mconcat, so there are certainly a myriad of applications.
You could also look at the First and Last newtype wrappers for Maybe a, I can think of many uses for those. The Endo wrapper is nice if you need to compose a lot of functions, the Any and All wrappers are good for working with booleans.