haskell - 避免重叠实例的更好方法是什么
问题描述
我正在尝试实现 Integral 类型类的 2 元组和 3 元组的行为。我还想为单个值定义行为,但我的方法似乎会导致类型错误。
{-# LANGUAGE FlexibleInstances #-}
class MyClass a where
prints :: a -> String
instance (Show n, Integral n) => MyClass (n, n) where
prints = show
instance (Show n, Integral n) => MyClass (n, n, n) where
prints = show
按预期工作。但是当我添加
{-# LANGUAGE UndecidableInstances #-} -- Adding this or else it wont compile
instance (Show n, Integral n) => MyClass n where
prints = show
我收到以下错误
*Main> prints 1
"1"
*Main> prints (1,1)
<interactive>:132:1: error:
• Overlapping instances for MyClass (Integer, Integer)
arising from a use of ‘prints’
Matching instances:
instance [safe] (Show n, Integral n) => MyClass n
-- Defined at question.hs:12:10
instance [safe] (Show n, Integral n) => MyClass (n, n)
-- Defined at question.hs:6:10
• In the expression: prints (1, 1)
In an equation for ‘it’: it = prints (1, 1)
这些怎么可能是重叠的实例?以这种方式定义时,类型是否需要包装在构造函数中?有没有更好的方法来实现这样的目标?
解决方案
错误消息列出了重叠的实例:
Matching instances:
instance [safe] (Show n, Integral n) => MyClass n
-- Defined at question.hs:12:10
instance [safe] (Show n, Integral n) => MyClass (n, n)
-- Defined at question.hs:6:10
在这个特定示例中,这可能不是问题,因为两者具有相同的实现 ( show
)。然而,编译器并不知道这一点。
想象一下,您有两个不同的实例。例如,为了论证,您可能已将其中一个实例定义为:
prints x = show x ++ "foo"
现在,当你 go 时prints (1,1)
,编译器不知道要选择哪个实例。它不能随意选择一个,因为输出可能会有所不同。
在 OP 案例中,我认为最简单的解决方案是删除特定实例(即MyClass (n, n)
和MyClass (n, n, n)
),因为更一般的实例也涵盖了这些特定情况,并且具有相同的行为。
推荐阅读
- image - 防止 Image.network 编码图像 url
- java - 为什么我不能生成签名的 APK?
- wordpress - 如何/可能将指纹登录添加到移动 wordpress 网站?
- python - Openpyxl - 在字典中添加来自两个不同 Excel 行的键、值对
- sql - SQL Server 中按 GROUP BY 的子组平均值
- python - 使用 Python/Scrapy 返回 HTTP 500 代码的进程页面
- javascript - JavaScript 原型数组成员找不到 undefiend 的推送
- jquery - 如何隐藏显示以增加元素
- macos - 尝试访问 PCI 内存映射寄存器时 OS X 内核崩溃
- javascript - 使用 reloadGrid 时 JQGRID 坚持发布原始 postData 值