[GHC] #15347: QuantifiedConstraints: Implication constraints with type families don't work
GHC
ghc-devs at haskell.org
Sat Jul 7 01:29:48 UTC 2018
#15347: QuantifiedConstraints: Implication constraints with type families don't
work
-------------------------------------+-------------------------------------
Reporter: aaronvargo | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler (Type | Version: 8.5
checker) | Keywords:
Resolution: | QuantifiedConstraints
Operating System: Unknown/Multiple | Architecture:
Type of failure: GHC rejects | Unknown/Multiple
valid program | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by aaronvargo):
Yes, that's what I wanted, but after thinking a bit, I think the current
behavior may actually be broken anyway!
Consider:
{{{#!hs
type family F a :: Constraint
yikes :: forall a b fb.
( a => fb
, fb ~ F b
)
=> Dict (Eq Int)
yikes = Dict
}}}
The above compiles, but with the current behavior, it actually violates
the open world assumption! Consider what happens if we now add:
{{{#!hs
type instance F a = Eq Int
}}}
{{{
• Could not deduce: a arising from a use of ‘Dict’
from the context: (a => fb, fb ~ F b)
bound by the type signature for:
yikes :: forall (a :: Constraint) b (fb :: Constraint).
(a => fb, fb ~ F b) =>
Dict (Eq Int)
• In the expression: Dict
In an equation for ‘yikes’: yikes = Dict
}}}
The problem is that since `fb ~ F b`, the `a => fb` constraint can overlap
if `F b` can be reduced further.
A possible solution is to always first reduce the heads of given
quantified constraints using given equalities. Then `a => fb` will become
`a => F b`, and won't be usable since `F b` isn't a valid instance head.
`qux` would then no longer compile, while `yikes` would continue to
compile even after the type instance is added.
My trick of floating out type families shouldn't even work!
I'm not sure that that even completely solves the problem
though...Consider:
{{{#!hs
type family F a :: Constraint
type instance F String = ()
whatAboutThis :: forall a b.
( F String => (b ~ Int)
, a => Eq b
) => Dict (Eq Int)
whatAboutThis = Dict
}}}
Currently this compiles. Should it?
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15347#comment:11>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list