Search code examples
haskellmonoids

Monoid Bool in Haskell


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?


Solution

  • 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