Haskell Language
Monoid
Suche…
Eine Instanz von Monoid für Listen
instance Monoid [a] where
mempty = []
mappend = (++)
Überprüfen der Monoid
Gesetze für diese Instanz:
mempty `mappend` x = x <-> [] ++ xs = xs -- prepending an empty list is a no-op
x `mappend` mempty = x <-> xs ++ [] = xs -- appending an empty list is a no-op
x `mappend` (y `mappend` z) = (x `mappend` y) `mappend` z
<->
xs ++ (ys ++ zs) = (xs ++ ys) ++ zs -- appending lists is associative
Eine Liste von Monoiden zu einem einzigen Wert zusammenfassen
mconcat :: [a] -> a
ist eine andere Methode der mconcat :: [a] -> a
Monoid
:
ghci> mconcat [Sum 1, Sum 2, Sum 3]
Sum {getSum = 6}
ghci> mconcat ["concat", "enate"]
"concatenate"
Die Standarddefinition lautet mconcat = foldr mappend mempty
.
Numerische Monoide
Zahlen sind auf zwei Arten monoidal: Addition mit 0 als Einheit und Multiplikation mit 1 als Einheit. Beide sind unter verschiedenen Umständen gleichermaßen gültig und nützlich. Anstatt eine bevorzugte Instanz für Zahlen auszuwählen, gibt es zwei newtypes
, Sum
und Product
um sie für die verschiedenen Funktionen zu newtypes
.
newtype Sum n = Sum { getSum :: n }
instance Num n => Monoid (Sum n) where
mempty = Sum 0
Sum x `mappend` Sum y = Sum (x + y)
newtype Product n = Product { getProduct :: n }
instance Num n => Monoid (Product n) where
mempty = Product 1
Product x `mappend` Product y = Product (x * y)
Dadurch kann der Entwickler effektiv auswählen, welche Funktionalität er verwenden soll, indem er den Wert in den entsprechenden newtype
.
Sum 3 <> Sum 5 == Sum 8
Product 3 <> Product 5 == Product 15
Eine Instanz von Monoid für ()
()
ist ein Monoid
. Da es nur einen Wert von type ()
gibt, gibt es nur eine mempty
, die mempty
und mappend
tun können:
instance Monoid () where
mempty = ()
() `mappend` () = ()