A monoid is a semigroup with an identity element. Formally, the identity element z is an element for which an equation, z + x = x + z = x, holds for any x. This equation is called identity property. Both closure and associativity properties that are defined for semigroups are also required to hold for a monoid.
The existence of the identity property requires us to implement the monoid, as follows:
trait Monoid[S] extends Semigroup[S] { def identity: S}
The check we specified for the semigroup also needs to be augmented for the monoid to verify that the new property holds:
def identity[S : Monoid : Arbitrary]: Prop = forAll((a: S) => { val m = implicitly[Monoid[S]] m.op(a, m.identity) == a && m.op(m.identity, a) == a })def monoidProp[S ...