阅读本书Real world Haskell
下面的重叠实例示例
instance (JSON a) => JSON [a] where
toJValue = undefined
fromJValue = undefined
instance (JSON a) => JSON [(String, a)] where
toJValue = undefined
fromJValue = undefined
ghci> toJValue [("foo","bar")]
<interactive>:1:0:
Overlapping instances for JSON [([Char], [Char])]
arising from a use of `toJValue' at <interactive>:1:0-23
Matching instances:
instance (JSON a) => JSON [a]
-- Defined at BrokenClass.hs:(44,0)-(46,25)
instance (JSON a) => JSON [(String, a)]
-- Defined at BrokenClass.hs:(50,0)-(52,25)
In the expression: toJValue [("foo", "bar")]
In the definition of `it': it = toJValue [("foo", "bar")]
根据我的理解,这不会是重叠,因为[a]不应该是一个选择,因为对JSON [a]的限制是'a'必须是JSON的实例本身。 (String,a)没有JSON实例。
答案 0 :(得分:19)
根据我的理解,这不会是重叠,因为
[a]
不应该是一个选择,因为对JSON [a]
的限制是a
必须是实例本身是JSON
。JSON
没有(String, a)
的实例。
这是一种误解。 GHC执行实例选择只考虑实例头,而不考虑实例的任何约束。
instance (JSON a) => JSON [a] where
表示实例选择的目的与
相同instance JSON [a] where
也是
的背景instance (JSON a) => JSON [(String, a)] where
实例选择会忽略。
因此GHC看到了两个实例
instance JSON [a]
instance JSON [(String, a)]
并且它们都匹配所需的
instance JSON [(String, String)]
这意味着你有重叠(无论实际存在什么实例以及这两个实例中的每个实例有什么限制)。
如果选择了实例,则会考虑约束,如果不满足,则为类型错误。
答案 1 :(得分:6)
这些存在
ghci> :i ToJSON
...
instance ToJSON [Char]
...
instance (ToJSON a, ToJSON b) => ToJSON (a, b)
即使GHC考虑了背景,也会有重叠(参见Daniel Fischer的回答)。