代码之家  ›  专栏  ›  技术社区  ›  Chris Stryczynski

当为String和List定义实例时,奇怪的“[Char]的重叠实例”

  •  0
  • Chris Stryczynski  · 技术社区  · 3 年前

    阅读这本书 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 回复  |  直到 3 年前
        1
  •  23
  •   Daniel Fischer    11 年前

    根据我的理解,这不会是重叠的,因为 [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)]
    

    这意味着您有重叠(无论实际存在什么实例以及两个实例中的每个实例都有什么约束)。

    如果选择了实例,则会考虑这些约束,如果不满足这些约束,则属于类型错误。

        2
  •  6
  •   J. Abrahamson    11 年前

    这些都存在

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

    因此,即使GHC考虑到上下文,也会有重叠(见Daniel Fischer的回答)。