Yes, but none of that has anything to do with a walk over the data type, as deriving(Functor) does! You are right that what we need is the result of simplifying the instantiated constraint (Generic [a], GC (Rep [a])) Simplify that constraint (simplifyDeriv does that), including reducing type-function applications, and that’s your context. But no need to look at the data type’s constructors, as deriving(Functor) does. Simon From: josepedromagalhaes@gmail.com [mailto:josepedromagalhaes@gmail.com] On Behalf Of José Pedro Magalhães Sent: 18 June 2016 09:16 To: Simon Peyton Jones <simonpj@microsoft.com> Cc: Ryan Scott <ryan.gl.scott@gmail.com>; Andres Löh <andres.loeh@gmail.com>; GHC developers <ghc-devs@haskell.org> Subject: Re: Inferring instance constraints with DeriveAnyClass I still don't think you can do it just from the default method's type. A typical case is the following: class C a where op :: a -> Int default op :: (Generic a, GC (Rep a)) => a -> Int When giving an instance C [a], you might well find out that you need C a =>, but this is not something you can see in the type of the default method; it follows only after the expansion of Rep [a] and resolving the GC constraint a number of times. Best regards, Pedro On Fri, Jun 17, 2016 at 12:43 PM, Simon Peyton Jones <simonpj@microsoft.com<mailto:simonpj@microsoft.com>> wrote: | My question is then: why does DeriveAnyClass take the bizarre approach | of co-opting the DeriveFunctor algorithm? Andres, you originally | proposed this in #7346 [2], but I don't quite understand why you | wanted to do it this way. Couldn't we infer the context simply from | the contexts of the default method type signatures? That last suggestion makes perfect sense to me. After all, we are going to generate an instance looking like instance .. => C (T a) where op1 = <default-op1> op2 = <default-op2> so all we need in ".." is enough context to satisfy the needs of <default-op1> etc. Well, you need to take account of the class op type sig too: class C a where op :: Eq a => a -> a default op :: (Eq a, Show a) => a -> a We effectively define default_op :: (Eq a, Show a) => a -> a Now with DeriveAnyClass for lists, we effectively get instance ... => C [a] where op = default_op What is ..? Well, we need (Eq [a], Show [a]); but we are given Eq [a] (because that's op's instantiated type. So Show a is all we need in the end. Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org<mailto:ghc-devs@haskell.org> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs<https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.haskell.org%2fcgi-bin%2fmailman%2flistinfo%2fghc-devs&data=01%7c01%7csimonpj%40064d.mgd.microsoft.com%7cb6b18be0b6ac490d83ae08d39750c6cf%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=hXiE2P63QGD4ZAFonWpDvqc0vKX%2fBPgPYVBAjIiaIXw%3d>