
#13404: Derive instances for classes with associated types -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- When trying to derive an instance of a class with associated types {{{#!hs import Data.Distributive import Data.Functor.Rep data Pair a = a :# a deriving Functor instance Distributive Pair where distribute :: Functor f => f (Pair a) -> Pair (f a) distribute = distributeRep instance Representable Pair where type Rep Pair = Bool index :: Pair a -> (Bool -> a) index (a :# _) False = a index (_ :# b) True = b newtype PAIR a = PAIR (Pair a) deriving (Functor, Representable) instance Distributive PAIR where distribute = {- distributeRep -} }}} {{{ • Can't make a derived instance of ‘Representable PAIR’ (even with cunning GeneralizedNewtypeDeriving): the class has associated types • In the newtype declaration for ‘PAIR’ }}} But it could create an instance {{{#!hs instance Representable PAIR where type Rep PAIR = Bool index :: forall a. PAIR a -> (Bool -> a) index = coerce (index :: Pair a -> (Bool -> a)) }}} Same with complicated expressions like {{{#!hs infixr 9 · type (·) = Compose newtype P f g h a = P (Product (f·g·f) (h·f·g) a) deriving (Functor, Foldable, Traversable, Applicative, Alternative, Distributive) instance (Functor f, Functor g, Functor h, Representable f, Representable g, Representable h) => Distributive (P f g h) where distribute = distributeRep instance (Functor f, Functor g, Functor h, Representable f, Representable g, Representable h) => Representable (P f g h) where type Rep (P f g h) = Either (Rep f, (Rep g, Rep f)) (Rep h, (Rep f, Rep g)) index :: (P f g h) a -> (Either (Rep f, (Rep g, Rep f)) (Rep h, (Rep f, Rep g)) -> a) index = coerce (index @(Product (f·g·f) (h·f·g))) tabulate :: (Either (Rep f, (Rep g, Rep f)) (Rep h, (Rep f, Rep g)) -> a) -> (P f g h) a tabulate = coerce (tabulate @(Product (f·g·f) (h·f·g))) }}} Is this too limited to work on general -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13404 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler