[GHC] #13404: Derive instances for classes with associated types

GHC ghc-devs at haskell.org
Mon Apr 24 14:31:08 UTC 2017


#13404: Derive instances for classes with associated types
-------------------------------------+-------------------------------------
        Reporter:  Iceland_jack      |                Owner:  (none)
            Type:  bug               |               Status:  closed
        Priority:  normal            |            Milestone:  8.2.1
       Component:  Compiler          |              Version:  8.0.1
      Resolution:  duplicate         |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:  #2721, #4083,     |  Differential Rev(s):
  #8165                              |
       Wiki Page:                    |
-------------------------------------+-------------------------------------
Changes (by RyanGlScott):

 * status:  new => closed
 * resolution:   => duplicate
 * related:  #4083 => #2721, #4083, #8165
 * milestone:   => 8.2.1


Comment:

 You're in luck, because this works in GHC 8.2. (In fact, I'll mark this as
 a duplicate of #2721/#8165.)

 This is the what the derived `Representable PAIR` instance is in the first
 example:

 {{{#!hs
 instance Representable PAIR where
     type Rep PAIR = Rep Pair
     tabulate = coerce @(forall (a :: Type). (Rep Pair -> a) -> Pair a)
                       @(forall (a :: Type). (Rep PAIR -> a) -> PAIR a)
                       tabulate
     index = coerce @(forall (a :: Type). Pair a -> Rep Pair -> a)
                    @(forall (a :: Type). PAIR a -> Rep PAIR -> a)
                    index
 }}}

 And in the second example:

 {{{#!hs
   instance (Representable h, Representable g, Representable f) =>
 Representable (P f g h) where
     type Rep (P f g h) = Rep (Product (f · (g · f)) (h · (f · g)))
     tabulate = coerce @(forall (a :: Type). (Rep Product (·) f (·) g f (·)
 h (·) f g -> a) -> Product (·) f (·) g f (·) h (·) f g a)
                       @(forall (a :: Type). (Rep P f g h -> a) -> P f g h
 a)
                       tabulate
     index = coerce @(forall (a :: Type). Product (·) f (·) g f (·) h (·) f
 g a -> Rep Product (·) f (·) g f (·) h (·) f g -> a)
                    @(forall (a :: Type). P f g h a -> Rep P f g h -> a)
                    index
 }}}

 As you can see, the algorithm works by taking the newtype's underlying
 type and sticking the associate type family in front of it, so you get
 `type Rep PAIR = Rep Pair` and `type Rep (P f g h) = Rep (Product (f · (g
 · f)) (h · (f · g)))` (which expand to `Bool` and `Either (Rep f, (Rep g,
 Rep f)) (Rep h, (Rep f, Rep g))`, respectively). This requires
 `UndecidableInstances` to use, but then again, so does a bunch of other
 code that involves type families ;)

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


More information about the ghc-tickets mailing list