
Serge, and others | 1. Can you check what ghc-5.02.3 will report on the below small program | with DShow I don't have ghc 5.02 to hand, but here's what 5.04.3 says about the code you give. ghc-5.04.3 -fglasgow-exts -fallow-overlapping-instances -fallow-undecidable-instances Serge.hs Serge.hs:14: Could not unambiguously deduce (DShow [a]) from the context (DShow a) The choice of (overlapping) instance declaration depends on the instantiation of `a' Probable fix: Add (DShow [a]) to the type signature(s) for `f' Or add an instance declaration for (DShow [a]) arising from use of `dShows' at Serge.hs:14 In the definition of `f': dShows xs "" | 2. When GHC fails to select an instance among overlapping ones, it is | often useful to report advice to the user: "consider adding such and | such instance class assertion to a type context". In general it's quite hard to make suggestions that are never misleading. In this case GHC does suggest something, but it's wrong! GHC 6.08's message is this: Serge.hs:14:23: Overlapping instances for DShow [a] arising from a use of `dShows' at Serge.hs:14:23-34 Matching instances: instance [overlap ok] (DShow a) => DShow [a] -- Defined at Serge.hs:(7,0)-(9,45) instance [overlap ok] DShow String -- Defined at Serge.hs:11:0-42 (The choice depends on the instantiation of `a' To pick the first instance above, use -fallow-incoherent-instances when compiling the other instance declarations) In the expression: dShows xs "" In the definition of `f': f xs = dShows xs "" This is better, although it does not suggest adding (DShow [a]) to the context of f. Adding that could perhaps be possible. | 3. In my example with DShow, instance overlaps are really redundant. | I looked into Prelude.Show, showList, and their usage in List and | [Char]. I added an analogue of showList, and now DShow does not need | overlapping instances. | | 4. But there are other situations, when it is much simpler for a | programmer to declare overlapping instances than to apply tricks with | additional class methods. I don't know what you are actually suggesting here | 5. What the GHC developers think on my suggestion below with the user | defined preference for overlapping instances? I believe your suggestion is: where instances overlap, choose the most specific. Yes, that's possible, and GHC does exactly that *unless* the answer to the match can be changed by instantiating a type variable. Consider f :: DShow a => a -> String If I need (DShow [a]) inside f, then you say, I guess, choose the DShow [a] instance even though there is a (DShow [Char]) instance. But if I changed 'f' to give it a more specific type: f :: Char -> String then we would choose the DShow [Char] instance instead. So making the type signature more specific has changed the semantics of the program. This is precisely what the flag -fallow-incoherent-instances does. So you can get the behaviour you ask for by giving an extra flag. Simon