Reading between the lines, the documentation has the key:
Generic instances … correspond to
Semigroup
andMonoid
instances defined by pointwise lifting.
In more words: each generic type can be broken up into a tuple-like row of components, and the generic type admits a monoid/semigroup whenever every component in the row admits a monoid/semigroup. In your handwritten Semigroup
instance, the given code is agnostic as to the types of variables
and functions
; all that matters is that they already have Semigroup
instances of their own.
Let me answer the other question: where’s the monoid in the generated Rep
? Well, there isn’t one! The Rep
merely has a struct-like product of component types. If a monoid exists for each component, then a monoid for the entire struct exists (and is built from the obvious pointwise lifting!) but otherwise there isn’t a monoid derived from the struct itself. This should be a notable contrast from generic instances for e.g. Functor
, where every Rep
has exactly zero or one Functor
due to the algebra of the semiring of types (there is an underlying algebraic equation with at most one possible solution.)
Become a kernel contributor first. I don’t think it’s acceptable to stand outside a community and ask how you can control it by throwing money at it.