1

模块 A 导入模块 B 和 C

模块 B 导入实例 X

模块 C 导入实例 Y

X 和 Y 是公共类型类的实例。

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

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

这让我感到困惑,因为从 C 到 X 的唯一路径是:C -> A -> B. 这是应该的吗?另外,有没有办法解决这个问题?我可以接受肮脏的黑客攻击,因为这两个实例在正常情况下从不一起使用。特别是,我不想介绍幻像类型等。

4

2 回答 2

2

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

我认为 GHC (7.4.1) 或 cabal 有一个错误。第一次编译失败并出现上述重叠实例错误。但是,再做一次(两次都使用cabal-dev build)它成功了!我会解释为什么:

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

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

于 2013-05-18T14:31:45.047 回答
2

根据您在那里的类的外观,使用两个小型代理模块P和应该很容易解决这个问题,每个模块都具有与所需类Q相同的newtype ProxyXY包装器;GeneralisedNewtypeDeriving但是一个 importingmodule B和另一个 importing module C,所以他们实际上使用不同的实例。然后,您有两种类型P.ProxyXYQ.ProxyXY它们的行为相同,但前者使用 X 实例,而后者使用底层类型的 Y 实例。

(如果这就是您对“幻影类型”的意思,则不确定,但这些实际上是不同的。)

于 2013-05-18T12:37:52.423 回答