2013-05-27 38 views
8

Đọc cuốn sách Real world Haskell geting dưới đây ví dụ về trường hợp chồng chéotrường hợp chồng chéo trong 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")] 

Bằng hiểu biết của tôi điều này sẽ không thể là một chồng chéo, như [a] không phải là một sự lựa chọn, vì Việc hạn chế JSON [a] là 'a' phải là một cá thể của JSON. Không có thể hiện của JSON cho (String, a).

Trả lời

17

Bằng hiểu biết của tôi điều này sẽ không thể là một chồng chéo, như [a] không phải là một sự lựa chọn, vì Hạn chế về JSON [a]a phải một thể hiện bản thân của JSON. Không có phiên bản nào của JSON cho (String, a).

Đó là một sự hiểu lầm. GHC thực hiện việc lựa chọn cá thể chỉ lấy phần đầu của cá thể và không phải là bất kỳ ràng buộc nào đối với các cá thể.

instance (JSON a) => JSON [a] where 

nghĩa với mục đích lựa chọn ví dụ giống như

instance JSON [a] where 

cũng bối cảnh

instance (JSON a) => JSON [(String, a)] where 

bị lờ đi để lựa chọn ví dụ.

Như vậy GHC thấy hai trường hợp

instance JSON [a] 
instance JSON [(String, a)] 

và cả hai đều phù hợp với yêu cầu

instance JSON [(String, String)] 

đó có nghĩa là bạn có sự chồng chéo (bất kể những gì các trường hợp thực sự tồn tại và những gì trở ngại mỗi hai trường hợp có).

Nếu một cá thể được chọn, thì các ràng buộc được tính đến và nếu chúng không được đáp ứng, đó là lỗi kiểu.

+0

cảm ơn lời giải thích rất chi tiết –

+0

Nhân tiện: một chút sau đó trên cuốn sách chỉ ra rằng bạn có thể sử dụng "chồng chéo" để giải quyết "vấn đề" được mô tả trong câu trả lời này. Cá nhân, tôi không hiểu tại sao nó là như vậy .. hy vọng tôi sẽ grok nó một ngày. – Brendan

5

Những tồn tại

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

Vì vậy, có muốn được sự chồng chéo thậm chí nếu GHC mất bối cảnh vào tài khoản (xem câu trả lời Daniel Fischer).

Các vấn đề liên quan