The monoid-subclasses package has been released on Hackage. The package defines several classes that are richer than semigroups and monoids but less demanding than groups:
Reductive
provides the operator </>
which acts as a partial inverse of the semigroup <>
operator.
Cancellative
is a subclass of Reductive
that provides additional guarantees about the </>
operation result:
(a <> b) </> a == Just b
(a <> b) </> b == Just a
Every group (i.e., every Monoid a
with the operation inverse :: a -> a
) is a cancellative monoid where a </> b = Just (a <> inverse b)
but not every Cancellative
monoid is a group.
GCDMonoid is a subclass of Reductive
and Monoid
that provides the gcd
operation for getting the greatest common denominator for two given monoid values.
LCMMonoid is a subclass of Reductive
and Monoid
that provides the lcm
operation for getting the least common multiple for two given monoid values.
Monus provides the <\>
monus operation. The set difference is one familiar instance of this operation.
MonoidNull class provides the Boolean null
operation that checks if the argument monoid is mempty
.
Factorial and FactorialMonoid classes represent semigroups and monoids that can be split up into irreducible factors.
That's the theoretical point of view. From the practical point of view, the main purpose of the monoid-subclasses package is similar to that of ListLike - to provide unifying abstractions for various monoidal data types in Haskell, primarily String, ByteString, and Text. All three types are already instances of the Monoid class. While that abstraction is useful for building sequences of data, it doesn't help with deconstructing them.
That being said, there are two major differences in the goals of ListLike and monoid-subclasses:
The incremental-parser package can serve as a compact example of a parser library that can be applied to different input types thanks to monoid-subclasses. There is also picoparsec, a fork of attoparsec, and the heavy-duty grammatical-parsers library.
A more thorough description of the library design can be found in the Haskell Symposium 2013 paper Adding Structure to Monoids