Reputation: 1516
Reading the book Real world Haskell
geting below example of Overlapping instances
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")]
By my understanding this won't be a overlapping, as [a] shouldn't be a choice, since The restriction on JSON [a] was that 'a' must be an instance itself of JSON. There is no instance of JSON for (String, a).
Upvotes: 12
Views: 1493
Reputation: 74384
These exist
ghci> :i ToJSON
...
instance ToJSON [Char]
...
instance (ToJSON a, ToJSON b) => ToJSON (a, b)
So there'd be an overlap even if GHC took context into account (see Daniel Fischer's answer).
Upvotes: 6
Reputation: 183978
By my understanding this won't be a overlapping, as
[a]
shouldn't be a choice, since The restriction onJSON [a]
was thata
must be an instance itself ofJSON
. There is no instance ofJSON
for(String, a)
.
That's a misunderstanding. GHC does the instance selection taking only the instance head into account, and not any constraints on the instances.
instance (JSON a) => JSON [a] where
means for the purpose of instance selection the same as
instance JSON [a] where
also the context of
instance (JSON a) => JSON [(String, a)] where
is ignored for instance selection.
Thus GHC sees the two instances
instance JSON [a]
instance JSON [(String, a)]
and they both match the required
instance JSON [(String, String)]
that means you have overlap (regardless of what instances actually exist and what constraints each of the two instances has).
If an instance is selected, then the constraints are taken into account, and if they are not met, that is a type error.
Upvotes: 23