Of course the data type is not exact, but is this how (more or less) the Monoid Bool
is implemented?
import Data.Monoid
data Bool' = T | F deriving (Show)
instance Monoid (Bool') where
mempty = T
mappend T _ = T
mappend _ T = T
mappend _ _ = F
If so/not, what is the reasoning for making Bool
's mappend
an OR
versus AND
?
In Haskell, the Monoid typeclass (not to be confused with Monad) is a class for types which have a single most natural operation for combining values, together with a value which doesn't do anything when you combine it with others (this is called the identity element).
As we can see, Monoid in Haskell is a typeclass that has three methods: mempty , mappend , and mconcat . mempty is a value that doesn't impact the result when used together with the binary operation. In other words, it's the identity element of the monoid. mappend (or <> ) is a function that puts two monoids together.
There are two possible Monoid
instances for Bool
, so Data.Monoid
has newtypes to distinguish which one we intend:
-- | Boolean monoid under conjunction.
newtype All = All { getAll :: Bool }
deriving (Eq, Ord, Read, Show, Bounded, Generic)
instance Monoid All where
mempty = All True
All x `mappend` All y = All (x && y)
-- | Boolean monoid under disjunction.
newtype Any = Any { getAny :: Bool }
deriving (Eq, Ord, Read, Show, Bounded, Generic)
instance Monoid Any where
mempty = Any False
Any x `mappend` Any y = Any (x || y)
Edit: There are actually four valid instances as Ørjan notes
Your provided instance isn't a monoid.
mappend F mempty
mappend F T -- by definition of mempty
T -- by definition of mappend
so we've proven F <> mempty === T
, but for any monoid, x <> mempty === x
.
The unit for Any
is False
, and the unit for All
is True
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With