top | item 31183382

(no title)

chas | 3 years ago

Funny enough, monoids/semigroups are one of my favorite parts of Haskell and I really miss having an explicit abstraction for them in other languages.

A lot of the code I write is looping over all of the values of a data structure to either look for a certain condition being true (any/all boolean monoid), look for an extremal value (min/max semigroup), or combine all of the values in the data structure (sum/product/average monoid). The product of a monoid is also a monoid, so if you want to do two or more of those operations at once, the code remains simple and orthogonal while only traversing the structure once.

In particular, all of the those operations are nicely expressed as one-lines using foldMap (https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-F...). If you have a data structure called `xs` and each element in data structure has an integer field called `size` you can do the following by using foldMap with different Monoid instances.

Sum the sizes:

  let (Sum total_size) = foldMap (\x -> Sum (size x)) xs
Check if any size is greater than 5:

  let (Any over_threshold) = foldMap (\x -> Any ((size x) > 5)) xs
Do both in one pass:

  let (Sum total_size, Any over_threshold) = foldMap (\x -> (Sum (size x), Any ((size x) > 5))) xs 
Get the first entry with a size greater than 5:

  let (First over_threshold) = foldMap (\x -> First (if (size x) > 5 then Just x else Nothing)) xs
Get all entries with a size greater than 5:

  let over_threshold = foldMap (\x -> if (size x) > 5 then [x] else []) xs
Since all of these operations are associative, we can completely change the data structure or run the operations in parallel or concurrently and the code will still behave exactly the same. These nice properties mean that when I'm thinking about these sorts of tasks in any language, I think about what monoid or semigroup captures a given operation, rather than any of the mechanics of writing the loop. I find clarifies my thinking a lot.

discuss

order

No comments yet.