Haskell Language
Monoïde
Recherche…
Une instance de Monoid pour les listes
instance Monoid [a] where
mempty = []
mappend = (++)
Vérification des lois du Monoid
pour cette instance:
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
Réduire une liste de monoïdes en une seule valeur
mconcat :: [a] -> a
est mconcat :: [a] -> a
autre méthode de la classe de Monoid
:
ghci> mconcat [Sum 1, Sum 2, Sum 3]
Sum {getSum = 6}
ghci> mconcat ["concat", "enate"]
"concatenate"
Sa définition par défaut est mconcat = foldr mappend mempty
.
Monoïdes Numériques
Les nombres sont monoïdaux de deux manières: addition avec 0 comme unité et multiplication avec 1 comme unité. Les deux sont également valables et utiles dans différentes circonstances. Donc, plutôt que de choisir une instance préférée pour les nombres, il y a deux newtypes
, Sum
et Product
pour les marquer pour les différentes fonctionnalités.
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)
Cela permet effectivement au développeur de choisir la fonctionnalité à utiliser en encapsulant la valeur dans le newtype
approprié.
Sum 3 <> Sum 5 == Sum 8
Product 3 <> Product 5 == Product 15
Une instance de Monoid pour ()
()
est un Monoid
. Comme il n'y a qu'une seule valeur de type ()
, il n'y a qu'une seule chose que mempty
et mappend
pourraient faire:
instance Monoid () where
mempty = ()
() `mappend` () = ()