demoteMonoid :: (forall m. Monoid m => m) -> Semigroup m => Maybe m
demoteMonoid k = eval k where
eval :: MONOID m -> Semigroup m => Maybe m
eval = getOption . foldMap (Option . Just)
data MONOID a = NIL | SING a | MONOID a :<> MONOID a
deriving Foldable
instance Monoid (MONOID a) where
mempty = NIL
mappend = (:<>)
like http://comonad.com/reader/2015/free-monoids-in-haskell/
However, one might wonder what a free monoid would look like as something closer to a traditional data type. To construct that, first ignore the required equations, and consider only the generators; we get:
data FMG a = None | Single a | FMG a :<> FMG a
Make it actually do anything one day