你可以在Haskell中为一个类而不是整个类创建一个类的实例吗?

Lay*_*lez 8 haskell typeclass type-constraints

假设我想让所有数字成为一个实例Monoid.而不是Num像这样为每个人创建一个实例:

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

instance Monoid Float where
  mappend = (+)
  mempty = 0.0

-- etc
Run Code Online (Sandbox Code Playgroud)

有这样的事吗?

instance Num t => Monoid t where
  mappend = (+)
  mempty = 0
Run Code Online (Sandbox Code Playgroud)

编辑

有些人正在回答GHC扩展并警告潜在的问题; 我发现信息丰富,但我想我会坚持Sum,Product无论如何coerce.

Mic*_*eld 21

我将此解释为询问一个普遍的前提,而不是特别关于MonoidNum.

也许你可以通过启用语言扩展FlexibleInstances,UndecidableInstances和使用重叠实例来获得你写的工作.

但你可能不会想:它似乎 instance Num t => Monoid t where ...在说

"如果t是一个实例Num,这里是如何制作...... t的实例Monoid"

不幸的是,这不对.它实际上说的更像是

"这是如何制作First t的实例Monoid.,它必须t是一个实例Num.下一个......"

因此,如果您编写这样的实例声明,则无法编写任何其他实例声明.(至少不是没有OverlappingInstances,这会带来自己的问题.)


yai*_*chu 6

GHC允许您的定义启用一些语言扩展

{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}

instance Num t => Monoid t where
  mappend = (+)
  mempty = 0
Run Code Online (Sandbox Code Playgroud)

这会2 <> 3导致结果5.

但这与其他Monoid实例重叠,因此尝试"Hello" <> "World"使用错误评估结果:Overlapping instances for Monoid [Char]

所以,我认为简短的回答是:不.