重叠实例的脏黑客?

时间:2013-05-18 09:48:19

标签: haskell typeclass overlapping-instances

模块A导入模块B和C

模块B导入实例X

模块C导入实例Y

X和Y是常见类型类的实例。

实例X和Y的类型相同,即完全重叠。

当我单独使用B或C时,一切正常。当我导入它们(这里是A)进行一些比较测试(或基准测试)时,我在C中得到一个重叠的实例错误,说X和Y都匹配。

这令我感到困惑,因为从C到X的唯一路径是:C -> A -> B。这是怎么回事?还有,有办法解决这个问题吗?我很擅长使用脏黑客,因为这两个实例在正常情况下从不一起使用。特别是,我不想介绍幻像类型等。

2 个答案:

答案 0 :(得分:2)

根据您所拥有的课程类别,应该很容易通过两个小代理模块PQ来解决这个问题,每个模块都有newtype ProxyXY包装GeneralisedNewtypeDeriving {1}}到期望的班级;但是一个导入module B而另一个导入module C,所以他们实际使用不同的实例。然后,您有两种类型P.ProxyXYQ.ProxyXY,它们的行为相同,但前者使用X实例,而后者使用基础类型的Y实例。

(如果这与“幻影类型”的含义不同,那么这些实际上是something different。)

答案 1 :(得分:2)

好的,这不是一个严肃的答案,虽然它可以让我编译我的代码。

我认为GHC(7.4.1)或cabal有一个bug。第一次编译失败,并显示重复的实例错误。但是,再次这样做(两次都使用cabal-dev build)它成功了!我会解释原因:

第一次编译在编译C时停止。因此C和A未编译。重新编译,首先编译C,成功,然后编译A.我猜C现在可以编译,因为GHC没有从B中获取间接实例(因为C没有直接依赖于B,而A是在 C之后编译

所以,最后,这是一个由部分编译引起的问题,对我的问题来说确实是一个非常脏的黑客。