首页 > 解决方案 > 在 Haskell 中创建 Eq 类型类的实例时出错

问题描述

我正在学习 Haskell 并编写一个小型决策图库作为一个起始项目。我已将数据类型声明为

data DD a = DDNode { var :: Int, vals :: [DD a]} | DDLeaf { val :: a} deriving (Show, Eq)

为了测试 2 个 DD 之间的相等性,我正在为 DD 创建一个 Eq 实例。它基本上与在树结构的情况下测试节点和叶相等性相同。

instance (Eq a) => DD a where
    (DDNode i vs) == (DDNode i' vs') = i == i' && vs == vs'
    (DDLeaf v) == (DDLeaf v') = v == v'
    _ ==  _ = False

当我在 GHCi 中使用上述代码加载文件时,出现以下错误,

Prelude> :load decisionDiagrams.hs
[1 of 1] Compiling DecisionDiagram  ( decisionDiagrams.hs, interpreted )

decisionDiagrams.hs:9:19: error:
    ‘==’ is not a (visible) method of class ‘DD’
Failed, modules loaded: none.

我究竟做错了什么?

标签: haskelltypeclass

解决方案


您不能在声明Eqderivinginstance声明中同时使用,因为那时有两种实现。因此deriving (Eq)应该删除:

data DD a
  = DDNode { var :: Int, vals :: [DD a]}
  | DDLeaf { val :: a}
  deriving (Show)

您需要指定要定义 的实例Eq,因此instance声明应如下所示:

--                 ↓ defining an instance for Eq
instance (Eq a) => Eq (DD a) where
    -- …

您正在实现的Eq实例是 Haskell 可以自动派生的实例。因此,您不需要自己构建这样的实例:您可以使用deriving子句来做到这一点。因此没有理由Eq手动实施。


推荐阅读