
Nicolas Frisby wrote:
First off, thanks for the reply.
I am accustomed to GHC ignoring instance contexts as you mentioned. It's the "mostly" part that I'm curious about: mostly implies there's some phases that don't ignore context. Is that only the checking the type of the method definitions and absolutely nothing else? So it seems...
I just said "mostly" because I don't know exactly... Though I strongly suspect, like you, that the preconditions are only used in type inference/checking and not for overlapping instances and similar questions related to uniqueness of instance declarations.
My project is rather committed to GHC, but could you elaborate on your reference to Hugs being different?
By tradition from Gofer, Hugs implements type classes more flexible than GHC does. I once experimented with the following code using overlapping instances:
data Lift a = Lift a type Test = Char
class Message m o where send :: m -> o -> Test
instance Message (o -> Test) o where send m o = m o
instance Message m o => Message m (Lift o) where send m (Lift o) = send m o
msg :: Test -> Test msg = id
r1 = send msg 'a' r2 = send msg (Lift 'b')
It implements some kind of subtyping. GHC won't typecheck this but "hugs -98 +m" will. If I remember correctly, the problem was with instance Message (Lift a -> Test) (Lift a) Does this follow from the first or from the second instance declaration? GHC ignores the precondition in the second declaration, thus believes it follows from both and consequently rejects it. But Hugs has no problems with that: it follows the precondition and sees that the second declaration does not apply to the culprit because there is no (instance (Lift a -> Test) a). Note that if you add this instance later on (perhaps in a different module), things will break. The flexibility comes at a price: Gofer's type class system was unsound and I don't know how much Hugs comes close to this. Regards, apfelmus