为什么Int不实现'Monoid'?

Kev*_*ith 23 haskell

鉴于Maybe Int,我试着mappend自己.

$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
Run Code Online (Sandbox Code Playgroud)

看着Maybe,我看到:

Monoid a => Monoid(也许是a)

由于Int没有实现Monoid类型类,这就解释了为什么我不能使用mappendMaybe Int.

但是,我记得LYAH我可以使用Sum:

ghci> let x = Sum 55
ghci> mappend x x
Sum {getSum = 110}
Run Code Online (Sandbox Code Playgroud)

但是,为什么不是IntMonoid?

Cir*_*dec 41

Int不是Monoid因为有不止一个明显的Monoid实现Int.

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

instance Monoid Int where
    mempty  = 1
    mappend = (*)
Run Code Online (Sandbox Code Playgroud)

newtype小号SumProduct定义在Data.Monoid让你轻松选择哪些Monoid情况下用数字来使用.

  • 其他有效的monoid实现:max和min(mempty分别是minBound和maxBound).有_lots_有效的实现. (8认同)
  • @KevinMeredith如果你正在使用GHC 7.8或更新,那么`Sum`和`Product`实现`Num`,所以你可以做`getSum $ mconcat $ take 10 $ iterate(+1)1`,尽管它们没有实现`Enum`所以你不能做`getSum $ mconcat [1..10]`.在第一个表达式中,您可以将`getSum`替换为`getProduct`,它仍然可以编译. (6认同)
  • 由于`Int`是固定大小,我们也有各种按位运算. (5认同)
  • ...更不用说它可能是最小值,最大值,第一个正数,等等. (3认同)
  • 我认为当一个类型允许同一类的多个合法实例时要遵循什么规则是一个有趣但并不总是显而易见的问题。在某些情况下,例如这里的“Int”和“Monoid”,选择是根本不实现该类,并将实例保留为“newtype”,因为没有明显的选择作为默认值。另一方面,在“Applicative []”实例的情况下,只有其中一个与“Monad”实例兼容,这决定了选择。还有像“Monoid Maybe”这样的情况,很多人不喜欢...... (2认同)