haskell - 在 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.
我究竟做错了什么?
解决方案
您不能在声明Eq
中deriving
和instance
声明中同时使用,因为那时有两种实现。因此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
手动实施。
推荐阅读
- python - 为什么线程在heroku中停止?
- django - 带有SPA的Django REST - 什么结构
- ios - Swift UICollectionView 工作奇怪,只注册第二次点击
- google-app-maker - 从应用程序制造商打印的可接受方式是什么?
- asp.net-core-3.0 - 为什么.Net Core 3.0 ViewComponent 中没有可用的 Request.Path
- node.js - curl-Command 返回 html 而不是 node.js
- java - 使@MockBean 在每个请求上返回新对象
- sql - INSERT OR REPLACE 多行,但没有唯一键或主键
- r - 如何在ggplot2中创建十字刻度线
- rust - Rust 语言中有哪些部分只能在多行上工作?