[GHC] #6134: Incorrect ambiguity error with functional dependencies

GHC cvs-ghc at haskell.org
Tue Jun 5 23:59:39 CEST 2012


#6134: Incorrect ambiguity error with functional dependencies
----------------------------------------+-----------------------------------
    Reporter:  diatchki                 |       Owner:                           
        Type:  bug                      |      Status:  new                      
    Priority:  normal                   |   Milestone:                           
   Component:  Compiler (Type checker)  |     Version:  7.4.1                    
    Keywords:                           |          Os:  Unknown/Multiple         
Architecture:  Unknown/Multiple         |     Failure:  GHC rejects valid program
  Difficulty:  Unknown                  |    Testcase:                           
   Blockedby:                           |    Blocking:                           
     Related:                           |  
----------------------------------------+-----------------------------------
Changes (by simonpj):

  * difficulty:  => Unknown


Comment:

 Right. This check, on user type signatures, is ''purely'' there to report
 types that cannot possibly be used.  So for example we want to reject:
 {{{
 f :: C [a] => Int
 }}}
 The idea is there can be no legal calls to `f` because every call will
 give rise to an ambiguous constraint.  We could soundly omit the ambiguity
 check on type signatures entirely, at the expense of delaying ambiguity
 errors to call sites.

 But is every call to `f` ambiguous?  After all, we might have
 {{{
 intance C [a] where ...
 }}}
 at the call site.  So maybe that type is ok!  What about the
 quintessentially ambiguous type
 {{{
 f :: C a => Int
 }}}
 Well, with `UndecidableInstances` we could have
 {{{
 instance C a where ...
 }}}
 and now a call could be legal after all!  (But only with
 `UndecidableInstances`.

 So it's clear that the present check is too conservative (rejects
 perfectly ok programs).  Using the visible fundeps is also too
 conservative.  Consider
 {{{
 class C a b where ...
 class D a b | a -> b where ...
 instance D a b => C [a] b where...

 f :: C a b => a -> a
 }}}
 Here `f`'s type looks ambiguous in `b`, but here's a legal call:
 {{{
 ...(f [True])...
 }}}
 That gives rise to a `(C [Bool] beta)` constraint, and using the instance
 means we need `(D Bool beta)` and that fixes `beta` via `D`'s fundep!

 So I think the only types we can reject as definitely ambiguous are ones
 like this
 {{{
   f :: (Cambig, Cnonambig) => tau
 }}}
 where
  * `Cambig`, `Cnonambig` are each a set of constraints.
  * `fv(Cambig)` does not intersect `fv( Cnonambig => tau )`
  * The constraints in `Cambig` are all of form `(C a b c)` where a,b,c are
 type variables
  * `Cambig` is non-empty
  * `-XUndecidableInstances` is not on.

 That narrows the scope of the test considerably.  Make sense?

 Simon

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/6134#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler



More information about the Glasgow-haskell-bugs mailing list