returning to instance overlap
Serge D. Mechveliani
mechvel at botik.ru
Fri Jan 18 04:32:35 EST 2008
Dear GHC developers,
can you exaplain, please, how to use overlapping instances?
For example, the following program uses overlapping instances for
DShow [a] and DShow String, but ghc-6.8.2 reports an error:
-----------------------------------------------------------------
class DShow a where dShows :: a -> String -> String
instance DShow Char where dShows = showChar
instance DShow Int where dShows = shows
instance DShow a => DShow [a] -- (1)
where
dShows _ = showString "contrived show value"
instance DShow String where dShows = shows -- (2)
f :: DShow a => [a] -> String
f xs = dShows xs ""
-- dShows (head xs) "" -- compare to this
main = putStr (shows (f "abc", f [1, 2, 3 :: Int]) "\n")
-----------------------------------------------------------------
I compile this under
-fglasgow-exts -fallow-overlapping-instances
-fallow-undecidable-instances
-fno-warn-overlapping-patterns -fwarn-unused-binds
-fwarn-unused-matches -fwarn-unused-imports
But the ghc-6.8.2 compiler reports
Overlapping instances for DShow [a]
arising from a use of `dShows' at IOverlap.hs:21:23-34
Matching instances:
instance [overlap ok] (DShow a) => DShow [a]
-- Defined at IOverlap.hs:(14,0)-(16,45)
instance [overlap ok] DShow String
-- Defined at IOverlap.hs:18: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 ""
1. Will ghc-5.02.3 find this program correct?
2. Applying -fallow-incoherent-instances leads to the result
"(contrived show value, contrived show value)"
for the function `main', which is not the point.
My idea was that in the above program f "abc" will choose the
instance (2), because String is a special case of [a].
3. Also DoCon uses overlapping instances, and works under ghc-6.8.2,
somehow (probably, I need to recall what precisely this usage is).
4. Maybe, it is good compile the above declaration
f :: DShow a => [a] -> String
f xs = dShows xs ""
by relating to dShows the _set_ S = {dShows of (1), dShows of (2)}
of two instances,
putting to the code the set of two implementations.
And when the complier comes (maybe in other module) to
(f "abc", f [1, 2, 3 :: Int]),
it chooses from S dShows of (2) for f in f "abc",
-- because [Char] is more special than [a].
And in f [1, 2, 3 :: Int], it chooses dShows of (1).
Thank you in advance for your explanation,
-----------------
Serge Mechveliani
mechvel at botik.ru
More information about the Glasgow-haskell-users
mailing list