[GHC] #8634: Relax functional dependency coherence check ("liberal coverage condition")

GHC ghc-devs at haskell.org
Mon Sep 4 08:08:47 UTC 2017


#8634: Relax functional dependency coherence check ("liberal coverage condition")
-------------------------------------+-------------------------------------
        Reporter:  danilo2           |                Owner:  (none)
            Type:  feature request   |               Status:  new
        Priority:  normal            |            Milestone:  8.4.1
       Component:  Compiler (Type    |              Version:  7.7
  checker)                           |
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:  #1241, #2247,     |  Differential Rev(s):  Phab:D69
  #8356, #9103, #9227                |
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by AntC):

 Replying to [comment:63 goldfire]:
 >
 > My understanding of `DysfunctionalDependencies` is much, much simpler:
 just omit the check that takes place at instance declarations. For
 example, the following would be accepted:

 Hereby confirming we can write Richard’s class `Terrible` today [GHC
 8.0.1]. Of course not directly like this:

 >
 > {{{
 > class Terrible a b | a -> b
 > instance Terrible Int Bool
 > instance Terrible Int Char
 > }}}
 >

 “Instances inconsistent with Functional Dependency”. But we can abuse
 GHC’s "bogus consistency check" ticket:10675#comment:15.

 {{{
 {-# LANGUAGE UndecidableInstances, … #-}
 class Terrible2 a b | a -> b
 instance {-# OVERLAPS #-} Terrible2 Int Bool
 instance {-# OVERLAPS #-} (b ~ Char) => Terrible2 Int b
 }}}

 If the usage site gives you wanted `b ~ Bool`, this uses the first
 instance. Otherwise it selects the second instance and improves to `b ~
 Char`.

 >
 > {{{
 > foo :: Terrible a b => a -> b
 > foo = undefined
 > }}}
 >
 > and we call `show (foo (5 :: Int))`. GHC has to figure out what type the
 argument to `show` has so it can supply the right `Show` instance. In this
 case, the type inferred for `foo (5 :: Int)` will either be `Bool` or
 `Char`, depending on the whims of GHC at the moment. They're called
 dysfunctional for a reason!
 >

 Want to choose one of those instances arbitrarily, in the absence of any
 wanted for `b`? Then just change the pragmas to `{-# INCOHERENT #-}`.

 You have more possible instances? Then repeat the trick. Instead of that
 second instance:

 {{{
 instance {-# INCOHERENT #-} (Terrible3 Int b) => Terrible2 Int b

 class Terrible3 a b | a -> b
 instance {-# INCOHERENT #-} Terrible3 Int Char
 instance {-# INCOHERENT #-} (Terrible4 Int b) =>  Terrible3 Int b

 -- context gives you the constructor only? Then you can improve the
 content:

 class Terrible4 a b | a -> b
 instance {-# INCOHERENT #-} (b’ ~ String) => Terrible4 Int (Maybe b’)
 instance {-# INCOHERENT #-} (Terrible5 Int b) => Terrible4 Int b
 }}}

 This is a (verbose) way to achieve a Closed Class. The thing we can’t get
 is per @Danilo’s O.P. with a free type var:

 {{{
 class Terrible5 a b | a -> b
 instance {-# INCOHERENT #-} (out ~ (t1 -> t1)) => Terrible5 Int out
 }}}

 Too liberal even for the Liberal Coverage Conditions.

 Perhaps if there’s a known set of choices for `t1` we could write out a
 class/instance for each? (With a default improvement at the end of the
 chain.)

 It's difficult to see this is any genuine variety of `FunDep`. It just
 evades the error you'd get in `show ( foo (5 :: Int) )` about an ambiguous
 type. I suppose we're lucky GHC has never applied the rule (from the
 original FunDeps paper) that if we have `Terrible Int b1` and `Terrible
 Int b2` then `b1 = b2` (that's identical types, not merely unifiable --
 not that they're even unifiable for `Terrible`).

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


More information about the ghc-tickets mailing list