
#10447: DeriveFoldable rejects instances with constraints in last argument of data type -------------------------------------+------------------------------------- Reporter: RyanGlScott | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: GHC rejects | Unknown/Multiple valid program | Test Case: Blocked By: | Blocking: Related Tickets: #8678 | Differential Revisions: -------------------------------------+------------------------------------- Comment (by RyanGlScott): I think it's entirely reasonable for a derived {{{Foldable Foo}}} instance not to fold over the {{{Int}}} argument. If it did fold over the {{{Int}}} argument, then the implementation of {{{foldr}}} and {{{foldMap}}} would have to pattern-match the {{{Refine}}} argument, making it resemble this: {{{#!hs instance Foldable Foo where foldr f z (Foo RefineI a2) = f a2 z foldr f z (Foo RefineD a2) = z foldMap f (Foo RefineI a2) = mappend mempty (f a2) foldMap f (Foo RefineD a2) = mappend mempty mempty }}} At this point, though, we are no longer defining {{{foldr}}} and {{{foldMap}}} in terms of the {{{Foldable Refine}}}. This feels off to me, since 1. Almost every other {{{deriving}}} typeclass extension dispatches to arguments' implementations of that particular typeclass (e.g., in {{{data Bar a = Bar (Maybe a) [a] deriving Show}}}, the derived {{{Show (Bar a)}}} instance relies on the {{{Show}}} instances for {{{Maybe a}}} and {{{[a]}}}). 2. If a user were to manually define an "untraditional" {{{Foldable}}} instance for {{{Refine}}}, the derived {{{Foldable Foo}}} instance wouldn't make use of it. In addition, requiring derived instances to pattern-match constructors of GADT arguments could break other code, e.g., {{{#!hs data Refine a where RefineI :: Refine Int RefineD :: Refine Double instance Functor Refine where fmap = undefined data Foo a = Foo (Refine a) Int deriving Functor }}} Since pattern-matching on {{{Refine}}} would refine the type of {{{fmap}}} in the derived {{{Functor Foo}}} instance to something that isn't universally polymorphic. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10447#comment:13 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler