【发布时间】:2018-09-01 08:14:31
【问题描述】:
并发症。
考虑以下 sn-p:
class D u a where printD :: u -> a -> String
instance D a a where printD _ _ = "Same type instance."
instance {-# overlapping #-} D u (f x) where printD _ _ = "Instance with a type constructor."
这就是它的工作原理:
λ printD 1 'a'
...
...No instance for (D Integer Char)...
...
λ printD 1 1
"Same type instance."
λ printD [1] [1]
...
...Overlapping instances for D [Integer] [Integer]
...
λ printD [1] ['a']
"Instance with a type constructor."
请注意,尽管提供了 pragma ,但重叠的实例并未解决 结束。
一个解决方案。
经过一番猜测才得出以下调整后的定义:
class D' u a where printD' :: u -> a -> String
instance (u ~ a) => D' u a where printD' _ _ = "Same type instance."
instance {-# overlapping #-} D' u (f x) where printD' _ _ = "Instance with a type constructor."
它像我预期的那样工作:
λ printD' 1 'a'
...
...No instance for (Num Char)...
...
λ printD' 1 1
"Same type instance."
λ printD' [1] [1]
"Instance with a type constructor."
λ printD' [1] ['a']
"Instance with a type constructor."
我的问题。
我很难理解这里发生了什么。有解释吗?
特别是,我可以提出两个单独的问题:
- 为什么在第一个 sn-p 中没有解决重叠?
- 为什么在第二个 sn-p 中解决了重叠?
但是,如果这些问题是相互关联的,也许一个单一的、统一的理论可以更好地解释这个案例。
附注关于关闭/重复投票 我知道~ 表示类型相等,我有意识地使用它来获得我需要的行为(特别是printD' 1 'a' 不匹配)。它几乎没有解释任何关于我提出的案例的具体内容,其中声明类型相等的两种方式(~ 和 instance D a a) 导致两种微妙不同的行为。
note 我用ghc8.4.3和8.6.0.20180810测试了上面的sn-ps
【问题讨论】:
-
@AJFarmar 另一个线程没有解决为什么这两个类型相等声明的问题(
instance D a a也是一个类型相等声明,不是吗?) 导致不同的行为。