In an attempt to design a elegant way to serialise things to any serialised form, I came up with the following exotic solution:
###
{-# OPTIONS -fallow-undecidable-instances -fallow-overlapping-instances #-}
module Convertable whereclass Convertable a b where convert :: a -> b
instance Convertable a a where convert = id
instance (Convertable a b,Convertable b c) => Convertable a c where convert = (convert :: b -> c) . (convert :: a -> b)
class (Convertable a b,Convertable b a) => Equivalent a b ###
Happily surprised to see GHC swallow this, I continued by adding
###
{-# OPTIONS -fallow-undecidable-instances -fallow-overlapping-instances #-}
module Serialise whereimport Convertable import Data.PackedString (PackedString,packString,unpackPS)
instance Convertable String PackedString where convert = packString
instance Convertable PackedString String where convert = unpackPS
instance (Show a) => Convertable a String where convert = show
instance (Read a) => Convertable String a where convert = read ###
But now GHC complains about overlapping instances:
"Overlapping instance declarations:
Serialise.hs:16: Convertable String a
Convertable.hs:7: Convertable a a"
Why can't GHC decide that the "Convertable String a" instance is more specific?
Apparently, there is no problem with the combination of "Convertable a a" and "Convertable a String": if I leave out "read", all is well. What is the difference with the above?
In the manual one can find:
"GHC is also conservative about committing to an overlapping instance. For example:
class C a where { op :: a -> a }
instance C [Int] where ... instance C a => C [a] where ...
f :: C b => [b] -> [b] f x = op x
From the RHS of f we get the constraint C [b]. But GHC does not commit to the second instance declaration, because in a paricular call of f, b might be instantiate to Int, so the first instance declaration would be appropriate. So GHC rejects the program. If you add -fallow-incoherent-instances GHC will instead silently pick the second instance, without complaining about the problem of subsequent instantiations."
I do not understand why GHC can't choose between C [Int] (whenever f is parametrised with Int) or C [a] (whenever f is parametrised with anything else). (While checking the type of f, it is clear that the constraint C [b] is always met.) (Adding -fallow-incoherent-instances did not change anything.)
Thanks a lot for putting up with my English and my dubious type constructions :-).
Regards,
Arie Peterson
BTW: I would like to use this opportunity to express my content: I think haskell is a wonderful language (never, ever anymore javascript :s) and GHC is a, uhm, glorious compiler :-).
_______________________________________________ Glasgow-haskell-users mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
