[GHC] #9918: GHC chooses an instance between two overlapping, but cannot resolve a clause within the similar closed type family
GHC
ghc-devs at haskell.org
Wed Dec 31 01:25:54 UTC 2014
#9918: GHC chooses an instance between two overlapping, but cannot resolve a
clause within the similar closed type family
-------------------------------------+-------------------------------------
Reporter: qnikst | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.8.3
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: None/Unknown | Unknown/Multiple
Blocked By: | Test Case:
Related Tickets: | Blocking:
| Differential Revisions:
-------------------------------------+-------------------------------------
Comment (by goldfire):
Replying to [comment:10 simonpj]:
> I conclude from this thread that
> * `OverlappingInstances` should probably obey the same rules as closed
type families, for consistency.
Generally agreed here, with the same reservations that Simon writes.
>
> I suppose that we could lift the restriction (ie strengthen the "surely-
apart" check) if some flag is set:
> * I believe that the unpredictability only strikes if you have infinite
types, via a looping type family. And a programmer might well be willing
to guaranteed that will not occur.
> * In that sense, it's a bit like `-XUndecidableInstances`: the
programmer takes responsibility.
> * And, as such it should probably be a per-type-family (or per-closed-
type-family) pragma, rather than a global flag. Maybe even `{-#
UNDECIDABLE #-}`.
I'm not sure exactly what you mean here (mostly). The `{-# UNDECIDABLE
#-}` route is almost surely a good idea, independent of anything else, as
it follows the new pattern started by `{-# OVERLAPPABLE #-}` and friends.
But, critically, a dangerous use of a strengthened apartness check would
happen on a family '''without''' this pragma. For example:
{{{
type family Equals a b where
Equals a a = True
Equals a b = False
}}}
This clearly has no loops and should compile without `{-# UNDECIDABLE
#-}`. Yet, if we use the strengthened apartness check when choosing to
reduce by the second equation, we can get into trouble. Specifically,
should `Equals x [x]` reduce to `False`, for some skolem `x`? If, in some
future module, we introduce `type family Loop where Loop = [Loop]`, then
it would be terrible to have reduced `Equals x [x]` to `False`. But, of
course, we have no way of knowing if `Loop` will come into being in the
future.
The nub of the problem, as I see it, is that the safety (for closed type
families) or predictability (for class instances) of the system depends on
some '''global''' no-looping property.
I could see some `{-# UNSAFE_STRONGER_APARTNESS_CHECK #-}` pragma that
could be put on `Equals` that would enable the stronger check and let the
programmer bear the safety burden. However, this is a significant
departure from other "let the programmer beware" issues in that, for
closed type families, you can abuse this ability to implement
`unsafeCoerce`. (This would not be the case for class instances.)
So, getting back to Simon's proposal: what's your suggested behavior? I
see what you want with `{-# UNDECIDABLE #-}`, but I don't see precisely
how it would influence the apartness check.
If we are going to start treating undecidable instances as different than
regular ones, it would be worthwhile to make the termination checker
smarter. Right now, a standard Peano multiplication type family requires
`-XUndecidableInstances`. I think the assumed safety of that extension (I
think folks are OK with a perhaps-looping compiler, as long as the
produced binary, if any, is type-safe) allows people to use it without
much hesitation, so there has been little (no?) pressure to improve the
termination checker.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9918#comment:13>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list