박신환
2018-05-02 14:31:55 UTC
Logical XOR is associative, also is XNOR. And they both have an identity element.
Hence:
newtype Even = Even {getEven :: Bool}
newtype Odd = Odd {getOdd :: Bool}
instance Semigroup Even where
(<>) = (==) -- (==) over Bool == Logical XNOR
instance Semigroup Odd where
(<>) = (/=) -- (/=) over Bool == Logical XOR
instance Monoid Even where
mempty = True
instance Monoid Odd where
mempty = False
So foldMap would determine the parity of the number of Trues.
Also, Monoid lifted by Applicative is also Monoid. This might be useful:
newtype AMonoid f a = AMonoid {getAMonoid :: f a}
instance (Applicative f, Semigroup a) => Semigroup (AMonoid f a) where
(<>) = liftA2 (<>)
instance (Applicative f, Monoid a) => Monoid (AMonoid f a) where
mempty = pure mempty
Hence:
newtype Even = Even {getEven :: Bool}
newtype Odd = Odd {getOdd :: Bool}
instance Semigroup Even where
(<>) = (==) -- (==) over Bool == Logical XNOR
instance Semigroup Odd where
(<>) = (/=) -- (/=) over Bool == Logical XOR
instance Monoid Even where
mempty = True
instance Monoid Odd where
mempty = False
So foldMap would determine the parity of the number of Trues.
Also, Monoid lifted by Applicative is also Monoid. This might be useful:
newtype AMonoid f a = AMonoid {getAMonoid :: f a}
instance (Applicative f, Semigroup a) => Semigroup (AMonoid f a) where
(<>) = liftA2 (<>)
instance (Applicative f, Monoid a) => Monoid (AMonoid f a) where
mempty = pure mempty