module MonoidDict where import Prelude hiding (Monoid(..)) -- -- * Monoid dictionary -- -- | A monoid is an algebraic structure with: -- 1. an identity element (0) -- 2. an associative binary operator (+) -- That obeys the following laws: -- 0 + x <=> x -- x + 0 <=> x -- (x + y) + z <=> x + (y + z) data Monoid a = MkMonoid a (a -> a -> a) -- | The identity element of a given monoid. mempty :: Monoid a -> a mempty (MkMonoid a _) = a -- | The associative binary operator of a given monoid. mappend :: Monoid a -> a -> a -> a mappend (MkMonoid _ f) = f -- Rewriting the laws using our dictionary: -- mappend d (mempty d) x <=> x -- mappend d x (mempty d) <=> x -- mappend d (mappend d x y) z <=> mappend d x (mappend d y z) -- NOTE: Can re-write the above definitions using "record syntax": -- -- data Monoid a = MkMonoid { -- mempty :: a, -- mappend :: a -> a -> a -- } -- -- * Instances -- -- | Pretend this is just the natural numbers. type Nat = Integer -- | Multiplication over the nats forms a monoid with identity element 1. natMul :: Monoid Nat natMul = MkMonoid 1 (*) -- | Addition over the nats with 0 forms a monoid. natAdd :: Monoid Nat natAdd = MkMonoid 0 (+) -- | Max over the nats with 0 forms a monoid. natMax :: Monoid Nat natMax = MkMonoid 0 max -- | List concatenation with empty list forms a monoid. listCat :: Monoid [a] listCat = MkMonoid [] (++) -- | Conjunction with true forms a monoid. boolAnd :: Monoid Bool boolAnd = MkMonoid True (&&) -- | Disjunction with false forms a monoid. boolOr :: Monoid Bool boolOr = MkMonoid False (||) -- | Function composition with the identity function forms a monoid. funComp :: Monoid (a -> a) funComp = MkMonoid id (.) -- -- * Derived operations -- -- | Fold the monoid operator over a list of elements. mconcat :: Monoid a -> [a] -> a mconcat d = foldr (mappend d) (mempty d) -- Now use this in GHCi to do cool things!