[GHC] #11523: Infinite Loop when mixing UndecidableSuperClasses and the class/instance constraint synonym trick.

GHC ghc-devs at haskell.org
Thu Jul 5 06:33:58 UTC 2018


#11523: Infinite Loop when mixing UndecidableSuperClasses and the class/instance
constraint synonym trick.
-------------------------------------+-------------------------------------
        Reporter:  ekmett            |                Owner:  simonpj
            Type:  bug               |               Status:  new
        Priority:  high              |            Milestone:  8.4.1
       Component:  Compiler (Type    |              Version:  8.0.1-rc1
  checker)                           |             Keywords:
      Resolution:                    |  UndecidableSuperClasses
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  GHC rejects       |            Test Case:
  valid program                      |  polykinds/T11523
      Blocked By:                    |             Blocking:
 Related Tickets:  #11480            |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by aaronvargo):

 Replying to [comment:14 simonpj]:
 > In this case, do you think that there is a finite tower of superclasses?
 I get
 > {{{
 > [G] Category p
 > +-> {add superclasses}
 >         Functor p
 >         Dom p ~ Op p
 >         Cod p ~ Nat p (->)
 >         Ob (Op p) ~ Ob p
 >
 > +-> {add superclasse of Functor}
 >         Category (Dom p)
 >         Cateogory (Cod p)
 > }}}
 > and now we merrily go round.  Adding `p ~ Op (Op p)` will help, because
 `Dom p ~ Op p`.  But we are still going to get `Cateogry (Cod p)`,
 `Category (Cod (Cod p))` and so on.  Is that really what you intend?

 What if you take instances into account in considering when to terminate?
 Then the tower is finite, since `Category (Cod p)` is a consequence of:

 {{{#!hs
 Category p
 Cod p ~ Nat p (->)
 instance (Category p, Category q) => Category (Nat p q)
 instance Category (->)
 }}}

 and so the fact that `Category (Cod p)` is a superclass provides no new
 information, and thus there's no need to go any further.

 This also suggests a slightly ugly work-around, which indeed seems to work
 (at least in this case):

 {{{#!hs
 -- Functor without Category (Cod f)
 class Category (Dom f) => Functor' (f :: i -> j)

 -- Functor with Category (Cod f)
 class (Functor' f, Category (Cod f)) => Functor f
 instance (Functor' f, Category (Cod f)) => Functor f

 -- only require Functor', since Category (Cod p) is already implied
 class ( Functor' p
       , Dom p ~ Op p
       , Cod p ~ Nat p (->)
       , Ob (Op p) ~ Ob p
       , Op (Op p) ~ p
       ) => Category (p :: Cat i)
 }}}

 Tangentially, there's also really no need for `Op p`, since it's just
 equal to `Dom p`, and so `Category` can be simplified to:

 {{{#!hs
 class ( Functor' p
       , Cod p ~ Nat p (->)
       , Dom (Dom p) ~ p
       , Ob (Dom p) ~ Ob p
       ) => Category (p :: Cat i)
 }}}

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


More information about the ghc-tickets mailing list