2015-04-07 3 views
18

Учитывая Maybe Int, я попытался сделать это mappend.Почему Int не реализует «моноид»?

$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 

Глядя на Maybe, я вижу:

Monoid а => Monoid (Может быть)

Поскольку Int не реализует Monoid типа класса, который объясняет, почему я могу Использовать mappend с Maybe Int.

Но я запомнила LYAH, что я могу использовать Sum:

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

Но, почему не Int Моноид?

ответ

34

Int не является Monoid, потому что существует более одного очевидного Monoid осуществления для Int.

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

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

newtype s Sum и Product определены в Data.Monoid позволяют легко выбрать, какой Monoid экземпляр для использования с номерами.

+0

Я должен был снова взглянуть на «Сумма» и «Продукт» - спасибо. –

+6

@KevinMeredith Если вы используете GHC 7.8 или новее, тогда 'Sum' и' Product' реализуют 'Num', поэтому вы можете сделать' getSum $ mconcat $ take 10 $ итерации (+1) 1', хотя они не реализуем 'Enum', поэтому вы не можете выполнить' getSum $ mconcat [1..10] '. В первом выражении вы можете обменять 'getSum' на' getProduct', и он все равно будет компилироваться. – bheklilr

+7

Другие допустимые моноидные реализации: max и min (с mempty minBound и maxBound соответственно). Имеются _lots_ правильных реализаций. –

Смежные вопросы