首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell,实现Monoids。什么是半群,为什么它表现得如此怪异?

Haskell,实现Monoids。什么是半群,为什么它表现得如此怪异?
EN

Stack Overflow用户
提问于 2022-07-25 15:09:01
回答 1查看 233关注 0票数 2

我想实现一个名为ComplexNumber的自定义数据类型,如下所示:data ComplexNumber a = C (a,a)

现在,我想实现Monoid变量,并定义二进制mappend元素和mappend,如下所示:

代码语言:javascript
复制
instance Num a => Monoid (ComplexNumber a) where
    mempty = C (0,0)
    mappend = (C (a1, b1)) (C (a2, b2)) = C (a1 + a2, b1 + b2)

但这并没有奏效,所以试着找出原因,并遇到了闪族(我仍然不太明白),于是找到了一种解决方案,它至少可以编译,并且似乎与此相配合:

代码语言:javascript
复制
instance Num a => Semigroup (ComplexNumber a) where
    (C (a1, b1)) <> (C (a2,b2)) = C (a1 + a2, b1 + b2)

instance Num a => Monoid (ComplexNumber a) where
    mempty = C (0,0)

有趣的是,当我删除半群的实现时,程序不再编译,并给出以下错误:

代码语言:javascript
复制
    * Could not deduce (Semigroup (ComplexNumber a))
        arising from the superclasses of an instance declaration
      from the context: Num a
        bound by the instance declaration at Aufgabe_10.hs:9:10-42
    * In the instance declaration for `Monoid (ComplexNumber a)'
  |
9 | instance Num a => Monoid (ComplexNumber a) where
  |  

为什么我可以将这两个部分编译在一起,但是当我移除半群时会发生错误?特别是这个半群的东西

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-25 15:18:10

Semigroup只是具有<>操作实现的所有类型的类,在某种程度上它是关联的(也就是说,如果我们忽略了小的浮点偏差,那么a<>(b<>c) ≡ (a<>b)<>c对你的复数来说是正确的)。

Monoid是半群的一类,它另外有一个中性元素mempty,即总是满足mempty <> a ≡ a <> mempty ≡ a的元素(对于带有加法和零的复数也是如此)。

对于一个甚至没有<>操作的类型来说,这是一个荒谬的要求,也就是说,它没有一个Semigroup实例。这是由Semigroup表示的,它是Monoid的超类,因此不可能有一个类型是Monoid的实例,而不是Semigroup的实例。

历史上,SemigroupMonoid是单独的类,旧的Monoid发布了自己的mappend操作,相当于现代的<>。一些旧的书籍/教程仍然基于这个旧的类层次结构。

但是由于有许多类型只是半群,而不是一元,所以类的层次结构发生了变化。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73111476

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档