數字么半群

數字是用兩種方式 monoidal: 除了以 0 為單位,和乘法以 1 為單位。兩者在不同情況下同樣有效且有用。因此,不是選擇數字的首選例項,而是有兩個 newtypesSumProduct 來標記它們以獲得不同的功能。

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)

這有效地允許開發人員通過將值包裝在適當的 newtype 中來選擇要使用的功能。

Sum 3     <> Sum 5     == Sum 8
Product 3 <> Product 5 == Product 15