[GHC] #3018: Constraints of function in record appears to
nullifiy instance constraints.
GHC
trac at galois.com
Wed Mar 4 10:11:49 EST 2009
#3018: Constraints of function in record appears to nullifiy instance constraints.
---------------------------------+------------------------------------------
Reporter: ben.kavanagh | Owner: simonpj
Type: bug | Status: new
Priority: normal | Milestone: _|_
Component: Compiler | Version: 6.10.1
Severity: normal | Resolution:
Keywords: | Difficulty: Unknown
Testcase: | Os: Unknown/Multiple
Architecture: Unknown/Multiple |
---------------------------------+------------------------------------------
Changes (by simonpj):
* owner: => simonpj
* difficulty: => Unknown
* milestone: => _|_
Comment:
Here are the key lines of code:
{{{
class Subst a t t' where
subst :: (Monad m) => a -> t -> t' -> m t'
data SubstD a t t'
= SubstD (forall m. Monad m => a -> t -> t' -> m t')
instance Data (SubstD a t) t' => Subst a t t' -- (1)
instance Subst a t t' => Sat (SubstD a t t') where -- (2)
dict = SubstD subst
}}}
The call to 'subst' on the last line gives rise to a constraint
`(Subst a t t')`. But that constraint can be satisfied in '''two
different ways''':
1. Using the instance declaration for `Subst` (which matches
''anything''!)
2. Using the context of the `Sat (SubstD ..)` instance declaration itself
If GHC uses (1) it gets into a corner it can't get out of, because now
it needs `(Data (SubstD a t) t')`, and that it can't get. The error
message
is a bit misleading:
{{{
T3018.hs:29:28:
Could not deduce (Data (SubstD a t) t') from the context (Monad m)
arising from a use of `subst' at T3018.hs:29:28-32
}}}
it should really say
{{{
...from the context (Subst a t t', Monad m)
}}}
but that's a bit of a separate matter.
Now, you are hoping that (2) will happen, but I hope you can see that it's
delicate.
Adding the `(Monad m)` context just tips things over the edge so
that GHC doesn't "see"
the `(Subst a t t')` in the context until too late. But the real problem
is
that you are asking too much. Here is a simpler example:
{{{
f :: Eq [a] => a -> blah
f x = let g :: Int -> Int
g = ....([x]==[x])...
in ...
}}}
The use of `==` requires `Eq [a]`, but GHC will probably use the list
equality
instance to simplify this to `Eq a`; and then it can't deduce `Eq a` from
`Eq [a]`.
Local constraints that shadow or override global instance declarations are
extremely delicate.
All this is perhaps soluble if GHC were to be lazier about solving
constraints,
and only makes the attempt when it has all the evidence in hand. I'm
thinking
quite a bit about constraint solving at the moment and will bear that in
mind.
But I can't offer you an immediate solution. At least I hope I've
explained the
problem.
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/3018#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the Glasgow-haskell-bugs
mailing list