the MPTC Dilemma (please solve)

Claus Reinke claus.reinke at talk21.com
Sat Feb 25 10:32:55 EST 2006


| Is the behaviour of GHC with -fallow-undecidable-instances (and
| -fcontext-stack) well-understood and specifiable? 
>I would not say that it's well-specified, no.  

to start improving that situation, could we please have a task ticket
for "document differences in unconstrained instance handling", then
ask everyone to attach source examples showing such differences?
[can guests attach code to task tickets?]

the hope being, of course, that implementations nominally providing
the same feature will eventually converge on providing the same
interpretation of all programs using that feature.

an example of the current oddities (at least they seem odd to me;): 
both hugs and ghc claim to resolve overlapping instances in favour 
of the most specific instance declaration. both claim that functional 
dependencies uniquely determine the range types from the domain 
types. but they do not agree on which programs to accept when 
we try to combine best-match with FDs.

I've already given an example where ghc allows me to define
record selection, while hugs complains that the overlap violates 
the FDs.

I reported that as a hugs bug, because I think the best-match
resolution of overlaps should ensure that the FD violation cannot
happen, so the code should be valid. there are different ways to
interpret FDs (something to check, or something to use), but it 
seemed that ghc was doing the right thing there. thread start:

http://www.haskell.org//pipermail/hugs-bugs/2006-February/001560.html

but after further experimentation, I'm not longer sure that ghc
is doing the right thing for the right reasons. here is a tiny example
of one of the disagreements:

{- ghc ok
   hugs "Instance is more general than a dependency allows" -}

class C a b | a -> b
instance C a b

so what is ghc doing there? is it going to guarantee that b will
always be uniquely determined?

{- ghc ok
   hugs "Instance is more general than a dependency allows" -}

class C b | -> b where c :: b
instance C b     where c = error "b"

safely m = m `CE.catch` print
main = do
  safely $ print $ (c::Int)
  safely $ print $ (c::Bool)
  safely $ print [id,c]

oh, apparently not. unless b is uniquely determined to be universally
quantified, and the instantiations happen "after" instance selection.

{- ghc ok
   hugs "Instance is more general than a dependency allows" -}

class C b | -> b where c :: b
instance C b     where c = error "b"

class D a where d :: a -> String
instance C a => D a where d a = "a"
instance C Int => D Int where d a = "Int"

-- try at ghci prompt:  (d 1,d (1::Int))
-- gives: ("a","Int")

so that parameter of C isn't all that unique. at least not long enough
to influence instance selection in D.

comments?

cheers,
claus



More information about the Haskell-prime mailing list