2013-05-27 43 views
8

阅读歌厅例如重叠的情况下书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的实例。

回答

17

按照我的理解,这将不会是重叠的,因为[a]不应该是一个选择,因为在JSON [a]的限制是,a必须是一个实例本身JSON(String, a)没有JSON的实例。

这是一个误解。 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)] 

,这意味着你有重叠(不管什么实际存在的情况下,以及每两个实例的限制具有)。

如果选择了一个实例,则会考虑约束条件,如果它们不符合,那就是类型错误。

+0

感谢您的非常详细的解释 –

+0

顺便说一句:稍后的书指出,你可以使用'OverlappingInstances'杂注来“解决”在这个答案中描述的“问题”。就我个人而言,我不明白为什么它是这样的......希望有一天我会饶舌它。 – Brendan

5

这些存在

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

所以有会是即使GHC了上下文考虑重叠(见丹尼尔·菲舍尔的答案)。

相关问题