> 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 #-} ? _______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users