类型类之间的关系 - 依赖与使用实例

时间:2015-05-23 09:39:55

标签: haskell typeclass

假设我想为semigroup和monoid定义自己的类型类。所以我写了这段代码:




  class Semigroup g where
 (<>):: g  - > g  - > g

类半群m => Monoid m where
 mempty :: m
  




但是还有另一种方法可以定义这些类型类之间的关系,并带有一些扩展:

&# xA;

  class Semigroup g where
 gappend :: g  - > g  - > g

类Monoid m其中
 mempty :: m
 mappend :: m  - > m  - > m

实例Monoid m =>半群m在哪里
 gappend = mappend
  




后一种设计有一个优势 - 后来我可以为Monoid添加更多实例。例如,如果我有一个矢量空间的类型类,我以后可以将它作为一个加法组而不必在类声明中指定它。另一方面,我被迫使用灵活的实例和不可判定的实例。





我的问题是 - 这个特定案例的最佳设计是什么?

& #xA;

1 个答案:

答案 0 :(得分:4)

第一个版本说" monoids是半群,附加属性为mempty"。

第二个确定说"所有类型都是半群,只要它们也是幺半群"。除非您乐意打开重叠实例,否则您无法添加任何其他实例,因此这等于"当且仅当它是一个幺半群时,类型才是半群&#34 ;;与真实关系完全相反。

我几乎总是喜欢前者。是的,它迫使有人想要添加Monoid实例来编写Semigroup实例,但真正的"工作"他们必须做同样的事情:决定memptymappend的实施。通过使用第二种方法,你唯一能够保存它们的是一个小样板。