阅读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")]
Run Code Online (Sandbox Code Playgroud)
根据我的理解,这不会是重叠,因为[a]不应该是一个选择,因为对JSON [a]的限制是'a'必须是JSON的实例本身.(String,a)没有JSON实例.
Dan*_*her 19
根据我的理解,这不会是一个重叠,因为
[a]不应该是一个选择,因为限制JSON [a]是a必须是一个实例本身JSON.没有JSONfor的实例(String, a).
这是一个误解.GHC执行实例选择仅考虑实例头,而不考虑实例的任何约束.
instance (JSON a) => JSON [a] where
Run Code Online (Sandbox Code Playgroud)
用于实例选择的目的与...相同
instance JSON [a] where
Run Code Online (Sandbox Code Playgroud)
也是的背景
instance (JSON a) => JSON [(String, a)] where
Run Code Online (Sandbox Code Playgroud)
被忽略的实例选择.
因此,GHC看到了这两个例子
instance JSON [a]
instance JSON [(String, a)]
Run Code Online (Sandbox Code Playgroud)
他们都符合要求
instance JSON [(String, String)]
Run Code Online (Sandbox Code Playgroud)
这意味着你有重叠(无论实际存在什么实例以及两个实例各有什么限制).
如果选择了实例,则会考虑约束,如果不满足,则表示类型错误.
这些存在
ghci> :i ToJSON
...
instance ToJSON [Char]
...
instance (ToJSON a, ToJSON b) => ToJSON (a, b)
Run Code Online (Sandbox Code Playgroud)
因此,即使GHC考虑了背景,也会有重叠(参见Daniel Fischer的回答).