Additionally, if the type s has any algebraic structure, act
m should be a homomorphism. For example, if s is also a
monoid we should have act m mempty = mempty and act m (s1
`mappend` s2) = (act m s1) `mappend` (act m s2).

By default, act = const id, so for a monoidal type M which
should have no action on anything, it suffices to write

Split monoids

Sometimes we want to accumulate values from some monoid, but have
the ability to introduce a "split" which separates values on
either side. For example, this is used when accumulating
transformations to be applied to primitive diagrams: the freeze
operation introduces a split, since only transformations occurring
outside the freeze should be applied to attributes.

Forgetful monoids

Sometimes we want to be able to "forget" some information. We
define two monoid transformers that allow forgetting information.
Forgetful introduces special values which cause anything to their
right to be forgotten. Deletable introduces special "left and
right bracket" elements which cause everything inside them to be
forgotten.

A value of type Forgetful m is either a "normal" value of
type m, which combines normally with other normal values, or a
"forgetful" value, which combines normally with other values to
its left but discards values combined on the right. Also, when
combining a forgetful value with a normal one the result is
always forgetful.

If m is a Monoid, then Deletable m (intuitively speaking)
adds two distinguished new elements [ and ], such that an
occurrence of [ "deletes" everything from it to the next ]. For
example,

abc[def]gh == abcgh

This is all you really need to know to useDeletable m
values; to understand the actual implementation, read on.

To properly deal with nesting and associativity we need to be
able to assign meanings to things like [[, ][, and so on. (We
cannot just define, say, [[ == [, since then ([[)] == [] ==
id but [([]) == [id == [.) Formally, elements of Deletable
m are triples of the form (r, m, l) representing words ]^r m
[^l. When combining two triples (r1, m1, l1) and (r2, m2, l2)
there are three cases:

If l1 == r2 then the [s from the left and ]s from the right
exactly cancel, and we are left with (r1, m1 <> m2, l2).

If l1 < r2 then all of the [s cancel with some of the ]s, but
m1 is still inside the remaining ]s and is deleted, yielding (r1
+ r2 - l1, m2, l2)

Applicative monoids

A wrapper for an Applicative structure containing a monoid.
Such structures have a Monoid instance based on "idiomatic"
application of mappend within the Applicative context.
instance Monoid m => Monoid (e -> m) is one well-known special
case. (However, the standard Monoid instance for Maybe is
not an instance of this pattern; nor is the standard instance
for lists.)

Coproduct monoid

m :+: n is the coproduct of monoids m and n. Values of
type m :+: n consist of alternating lists of m and n
values. The empty list is the identity, and composition is list
concatenation, with appropriate combining of adjacent elements
when possible.