Haskell Language
monoid
Ricerca…
Un'istanza di Monoid per gli elenchi
instance Monoid [a] where
mempty = []
mappend = (++)
Controllo delle leggi Monoid
per questa istanza:
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
Comprimere un elenco di mono in un unico valore
mconcat :: [a] -> a
è mconcat :: [a] -> a
altro metodo della Monoid
Monoid :
ghci> mconcat [Sum 1, Sum 2, Sum 3]
Sum {getSum = 6}
ghci> mconcat ["concat", "enate"]
"concatenate"
La sua definizione predefinita è mconcat = foldr mappend mempty
.
Monoidi numerici
I numeri sono monoidali in due modi: aggiunta con 0 come unità e moltiplicazione con 1 come unità. Entrambi sono ugualmente validi e utili in diverse circostanze. Quindi, piuttosto che scegliere un'istanza preferita per i numeri, ci sono due newtypes
, Sum
e Product
per taggarli per le diverse funzionalità.
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)
Ciò consente effettivamente allo sviluppatore di scegliere quale funzionalità utilizzare avvolgendo il valore nel newtype
appropriato.
Sum 3 <> Sum 5 == Sum 8
Product 3 <> Product 5 == Product 15
Un'istanza di Monoid per ()
()
è un Monoid
. Poiché esiste un solo valore di type ()
, c'è solo una cosa che mempty
e mappend
potrebbero fare:
instance Monoid () where
mempty = ()
() `mappend` () = ()