
#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