2015-04-07 12 views
18

Dato un Maybe Int, ho provato a mappend a se stesso.Perché Int non implementa 'Monoid'?

$let x = Just 55 :: Maybe Int 

$mappend x x 

<interactive>:126:1: 
    No instance for (Monoid Int) arising from a use of `mappend' 
    In the expression: mappend x x 
    In an equation for `it': it = mappend x x 

Guardando Maybe, vedo:

Monoide a => Monoide (Forse un)

Dal Int non implementa Monoid tipo di classe, che spiega perché posso utilizzare mappend con Maybe Int.

Ma, mi sono ricordato da LYAH che posso usare Sum:

ghci> let x = Sum 55 
ghci> mappend x x 
Sum {getSum = 110} 

Ma, perché non è un Int Monoide?

risposta

34

Int non è un Monoid perché è presente più di un'implementazione Monoid evidente per Int.

instance Monoid Int where 
    mempty = 0 
    mappend = (+) 

instance Monoid Int where 
    mempty = 1 
    mappend = (*) 

Il newtype s Sum e Product definito nel Data.Monoid consentono di selezionare facilmente quale Monoid esempio da utilizzare con i numeri.

+0

Avrei dovuto guardare di nuovo "Somma" e "Prodotto" - grazie. –

+6

@KevinMeredith Se stai usando GHC 7.8 o successivo, 'Sum' e' Product' implementano 'Num', quindi puoi fare' getSum $ mconcat $ prendere 10 $ iterate (+1) 1', sebbene non lo facciano implementa 'Enum' quindi non puoi fare' getSum $ mconcat [1..10] '. Nella prima espressione puoi scambiare 'getSum' per' getProduct' e sarà ancora compilato. – bheklilr

+7

Altre valide implementazioni monoidali: max e min (con mempty rispettivamente minBound e maxBound). Ci sono _lot_ di implementazioni valide. –

Problemi correlati