[GHC] #15974: QuantifiedConstraints: Spurious error involving superclass constraints

GHC ghc-devs at haskell.org
Thu Nov 29 19:43:54 UTC 2018


#15974: QuantifiedConstraints: Spurious error involving superclass constraints
-------------------------------------+-------------------------------------
        Reporter:  lexi.lambda       |                Owner:  (none)
            Type:  bug               |               Status:  closed
        Priority:  normal            |            Milestone:  8.6.3
       Component:  Compiler          |              Version:  8.6.2
      Resolution:  invalid           |             Keywords:
                                     |  QuantifiedConstraints
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  GHC rejects       |  Unknown/Multiple
  valid program                      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------
Changes (by lexi.lambda):

 * status:  new => closed
 * resolution:   => invalid


Comment:

 I discovered #14831, which is superficially related to this ticket, but I
 think the issues are actually distinct. The issue in that ticket is that
 GHC has //two different// options for solving a constraint, and it picks
 the wrong one. After reading some of the discussion there, however, I
 think I understand what’s going on in this ticket, and I don’t think it’s
 an issue with GHC making the wrong choice, but rather GHC having only one
 choice to make.

 In the program in the ticket, GHC is performing the following steps:

 1. GHC attempts to solve the superclass constraint `A (X f)` when
 declaring the `B (X f)` instance.

 2. Since the only way to get there is through the instance declaration for
 `A (X f)`, it then tries to solve the (quantified) instance context,
 `forall a. A a => A (f a)`.

 3. GHC then attempts to solve `A (f a)`, assuming it has `A a`, and it
 only has one path to get there, which is through `B (f a)` (via the
 superclass relationship).

 4. It then tries to solve `B a`, since that is the quantified context of
 `B (f a)`, and it gets stuck.

 This suggests a fix: add `forall a. A a => A (f a)` to the instance
 context for `B (X f)`. And indeed, the following declaration is accepted!

 {{{#!hs
 instance (forall a. A a => A (f a), forall a. B a => B (f a)) => B (X f)
 }}}

 This is unintuitive to me, since when I write, say, `Eq` and `Ord`
 instance on a datatype, I merely write them like

 {{{#!hs
 instance Eq a => Eq (List a)
 instance Ord a => Ord (List a)
 }}}

 not like

 {{{#!hs
 instance Eq a => Eq (List a)
 instance (Eq a, Ord a) => Ord (List a)
 }}}

 …but this works out only because `Ord a` entails `Eq a`. In this case,
 `forall a. B a => B (f a)` does **not** actually entail `forall a. A a =>
 A (f a)`, so I guess this is not actually a bug.

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


More information about the ghc-tickets mailing list