如何解决 Haskell 代码错误“<>' 不是类 `Monoid' 的(可见)方法”?

Has*_*bit 3 haskell monoids semigroup

让我们看看 Haskell 中用于处理反向列表的新数据类型的声明:

import Data.Monoid 
data RevList a = Nil | RCons (RevList a) a deriving (Eq, Show)

instance Monoid a => Monoid (RevList a) where
    mempty = Nil

instance Semigroup a => Monoid (RevList a) where
    Nil <> RCons (RevList a) a = RCons (RevList a) a
    RCons (RevList a) a <> RNil = RCons (RevList a) a
    Nil <> Nil = Nil
Run Code Online (Sandbox Code Playgroud)

我困扰的问题是编译失败,其描述如下:

 `<>' is not a (visible) method of class `Monoid'
Run Code Online (Sandbox Code Playgroud)

首先,我尝试在没有任何 Semigroup 实例声明的情况下创建一个 Monoid 实例,但是在阅读此问题后,它导致了另一个失败。那么,当前内容中的“<>”有什么问题?可以肯定的是,我知道缺少像 mappend 或 mconcat 这样的 Monoid 函数被添加到 Monoid 实例代码中作为强制函数。

Ale*_*nov 5

定义的实例<>应该是 for Semigroup (RevList a),而不是 for Monoid (RevList a),因为<>是一个Semigroup方法。

我知道缺少像 mappend 或 mconcat 这样的 Monoid 函数作为强制函数添加到 Monoid 实例代码中

它们实际上不是强制性的,你可以从

最小完整定义

mempty
Run Code Online (Sandbox Code Playgroud)

http://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Monoid.html 中

您实际上也没有在实例中使用约束(之前的部分=>);例如,你是不是叫mempty :: a你实现mempty :: RevList a。所以他们可以被删除,你最终

instance Monoid (RevList a) where
    mempty = RNil

instance Semigroup (RevList a) where
    RNil <> RCons (RevList a) a = RCons (RevList a) a
    RCons (RevList a) a <> RNil = RCons (RevList a) a
    RNil <> RNil = RNil
Run Code Online (Sandbox Code Playgroud)