In short: your definition for (<>)
can not be used as the binary operator for a monoid. Unless one can guarantee that there is only one possible value for a
(or b
if we use Snd
as the constructor for a "neutral element").
according to the above rules, apparently a Fst x
should be the mempty
if it was a Monoid
.
Exactly, if it was a monoid [wiki]. But for a monoid it can be proven that there exists *exactly one identity element. The proof is as follows: given there are two neutral elements e1 and e1, then it means that e1⊕e2=e1, but at the same time e1⊕e2=e2 (since a⊕e=e⊕a=a holds with e an identity element), so that means that e1=e2 holds, and thus the two are the same.
Now in your definition of (<>)
there is no such identity element. Indeed, say that this element is Fst e
, then it should hold that:
Fst e <> Fst a = Fst a
which holds (the first line of your definition), but it should also hold that:
Fst a <> Fst e = Fst a
and this will, according to your (<>)
function only hold if a
is e
. The only way we can thus declare this a monoid is if we can only define one value in the Fst
constructor, like @leftroundabout says, for example:
instance Monoid (Or () b) where
mempty = Fst ()
mappend = (<>)
We can thus conclude that your (<>)
function is not suited as a binary operator for a monoid. You will need to come up with a different binary operator that is structured in such a way that this can be used in a monoid.
Now it could still be possible that the identity element is of the form Snd e
, but then again:
(Snd x) <> (Snd e) = Snd x
(Snd e) <> (Snd x) = Snd x
should both hold, whereas in your implementation:
(Snd x) <> (Snd _)= Snd x
the latter will not hold (since x
can be different from e
).