gpt4 book ai didi

haskell - 帮助解释重叠实例错误消息

转载 作者:行者123 更新时间:2023-12-01 01:27:29 26 4
gpt4 key购买 nike

我被这个重叠实例错误消息难住了。抱歉,这是一个重要的项目,但错误应该是类型签名的本地错误。

首先,我声明 f 是某种类型,

let f = undefined :: (CompNode Int)

然后,我尝试调用我的函数 pshow :: PrettyShow a => a -> String在上面。我收到此错误消息。
> pshow f

<interactive>:1:1:
Overlapping instances for PrettyShow (CompNode Int)
arising from a use of `pshow'
Matching instances:
instance (G.Graph g, PrettyShow (G.Vertex g)) => PrettyShow g
-- Defined at Graph.hs:61:10-57
instance (PrettyShow a, Show a) => PrettyShow (CompNode a)
-- Defined at Interpreter.hs:61:10-58

问题是 CompNode Int不是图表,所以我认为第一个匹配的实例不应该被触发。 (第二个是我想要执行的那个。)确实,如果我编写一个函数,要求其参数为图形,
> :{
| let g :: G.Graph a => a -> a
| g = id
| :}

然后在 f 上调用它,我得到预期的无实例错误消息,
> g f

<interactive>:1:1:
No instance for (G.Graph (CompNode Int))

提前致谢,抱歉众包。我正在使用 GHC 7.0.4。

最佳答案

The problem is that CompNode Int is not a graph, so I don't think the first matching instance should be triggering.



你会这么想,但不幸的是它不会那样工作。

GHC在选择实例时,只看头部,即类名后面的部分。只有在实例选择完成后,它才会检查上下文,即 => 之前的部分。 .上下文中的不匹配会导致实例被拒绝并导致类型检查错误,但它们不会导致 GHC 回溯并寻找另一个实例。

因此,鉴于这些情况:
instance (G.Graph g, PrettyShow (G.Vertex g)) => PrettyShow g

instance (PrettyShow a, Show a) => PrettyShow (CompNode a)

...如果我们忽略上下文,它们看起来像这样:
instance PrettyShow g

instance PrettyShow (CompNode a)

这应该清楚地表明,第一个实例是完全通用的,并且绝对与所有内容重叠。

在某些情况下,您可以使用 OverlappingInstances扩展,但这不会改变上述行为;相反,它让 GHC 通过选择唯一的最具体的实例(如果存在)来解决模棱两可的实例。但是使用重叠实例可能会很棘手并导致神秘的错误,因此我鼓励您首先重新考虑设计,看看是否可以完全避免这个问题。

也就是说,在这里的特定示例中, CompNode a确实是 CompNode Int 的明确更具体的匹配,所以 GHC 会选择它而不是一般实例。

关于haskell - 帮助解释重叠实例错误消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6810940/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com