Please Depend on SemigroupsPosted on October 25, 2017
An Abridged History of Semigroup in Haskell
Monoids have been a ubiquitous part of modern functional programming for many years. Recently Semigroups, which are more general but weaker than monoids, have seen a lot of use as well.
At the time
Monoid was added to base, a
Semigroup class was not added alongside it. In hindsight, we would have liked a
Semigroup class as a superclass of
Monoid. Every Monoid is a Semigroup, and there are lots of useful structures that are only semigroups, like
NonEmpty lists. NonEmpty Lists lack the empty list, which is the identity of the append operation. Other useful structures come about that are related to Semigroup but don’t need a full Monoid, such as
Foldable1. Hence Edward Kmett wrote a library called semigroups. The package provides the
Semigroup class and
NonEmpty lists. Due to the usefulness of the abstraction, and the fact that many of Edward’s other packages depend on it, the semigroups package is very widely used.
NonEmpty were added to
base in version 4.91, meaning that anyone using GHC 8.0 or higher would get them for free, without any external dependencies.
Why your library should still depend on
Now that base has semigroups, it is tempting to remove our dependencies on the semigroups package and deprecate it out of existence. But there is a good reason to still depend on it: supporting older GHCs.
If you use the
Semigroup typeclass without depending on the semigroups package, your code will only run on GHC >= 8.0. But at the time of writing, several popular operating systems are still shipping GHC 7.10, and there are probably plenty of people stuck on older versions for their particular project or team. Adding a semigroups dependency helps the community, because it can make the difference between your library being usable for someone or unusable.
But looking at the module names in the semigroups package, it would seem they will clash with the modules recently added to base! Thankfully this is not the case, because semigroups is smart enough to “turn itself off” with CPP when it detects a new enough base version.
In summary, please depend on semigroups if you depend on
We’re using functional programming to set up the infrastructure that we use from day to day.
George Wilson is an enthusiastic programmer at the Queensland Functional Programming Lab. George enjoys writing code, and speaking and writing about Haskell and functional programming.