12

阅读本书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 实例。

4

2 回答 2

23

据我了解,这不会是重叠的,[a]也不应该是一个选择,因为对 is 的限制必须JSON [a]是. 没有for 的实例。aJSONJSON(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)]

这意味着您有重叠(无论实际存在哪些实例以及两个实例中的每一个具有哪些约束)。

如果选择了一个实例,则考虑约束,如果不满足,则为类型错误。

于 2013-05-27T15:50:42.463 回答
6

这些存在

ghci> :i ToJSON
...
instance ToJSON [Char]
...
instance (ToJSON a, ToJSON b) => ToJSON (a, b)

因此,即使 GHC 将上下文考虑在内,也会存在重叠(请参阅 Daniel Fischer 的回答)。

于 2013-05-27T15:22:57.527 回答