Liberalising IncoherentInstances
AntC
anthony_clayden at clear.net.nz
Mon Jul 29 03:33:08 CEST 2013
> Simon Peyton-Jones <simonpj <at> microsoft.com> writes:
>
> I've realised that GHC's -XIncoherentInstances flag is,
> I think, over-conservative.
Hi Simon, by coincidence I've just come across a very similar issue with
overlapping instances and FunDeps (following-up some discussion with Oleg,
MartinS, EdwardK).
Starting with:
class C a b | a -> b where foo :: a -> b
instance C [a] [a] where foo = id
t1 = foo "a" -- t1 :: [Char] -> [Char]
I then added:
instance C [Char] [Char] where foo = id
-- more specific!
t2 = foo "a" -- t2 :: C [a] [a] => [a] -> [a]
-- more polymorphic!
My (probably subjective) experience is that somewhere around 2006 when
Type Families started appearing, there were some subtle changes around
overlaps. TF's seemed to be very pre-occupied with supporting 'coincident'
(or confluent) _partial_ overlap.
(By partial overlap I mean: some substitutions match both instances, some
only one, some only t'other. This seems to be the root of the issue with
Joachim's post on ghc-devs.)
Partial overlaps are always going to be awkward for IncoherentInstances.
With Type Families, you can always check that the result is confluent. But
for class instances there's no such algebraic/semantic check possible.
It's easy to avoid partial overlaps: just define an instance for the mgu
of the overlap; then both of the less-specific instances totally overlap
it.
With the benefit of hindsight, I would have banned partial overlaps. IMO
we could then validate class instance 'eagerly' at point of declaration
(as Hugs does), rather than paying the penalty later with hazy/lazy
instance selection woes.
I strenuously try to avoid needing IncoherentInstances. I've no objection
to your proposed "liberalise a bit".
>
> Incidentally, I think it'd be an improvement to localise the
Overlapping/Incoherent flags to particular
> instance declarations, via pragmas, something like
> instance C [a] where
> {-# ALLOW_OVERLAP #-}
> op x = ....
>
> Similarly {-# ALLOW_INCOHERENT #-}. Having -XOverlappingInstances for
the whole module is a bit crude.,
> and might be missed when looking at an instance. How valuable would
this be?
>
+1
I strongly support localising these flags. Very seldom do I want
Overlapping for every class in a module, and I'd rather the compiler told
me if I inadvertently did overlap an instance.
Better still, can we do {-# DISALLOW_PARTIAL #-} ?
More information about the Glasgow-haskell-users
mailing list