
Hi Pedro, I'm quite confused by a peculiarity of deriving Data (more info in Trac #13327 [1]). In particular, if you write this: data T phantom = T deriving Data Then the derived Data instance is NOT this: instance Typeable phantom => Data (T phantom) where ... But instead, it's this: instance Data phantom => Data (T phantom) where ... dataCast1 f = gcast1 f The gcast1 part is why it requires the stronger (Data phantom) context, as you noted in Trac #4028 [2]. What confuses me, however, is that is apparently does not carry over to poly-kinded datatypes. For instance, if you write this: data T (phantom :: k) = T deriving Data Then you do NOT get this instance: instance Data (phantom :: *) => Data (T phantom) where ... dataCast1 f = gcast1 f But instead, you get this instance! instance (Typeable k, Typeable (phantom :: k)) => Data (T phantom) where ... -- No implementation for dataCast1 This is quite surprising to me. I'm not knowledgeable enough about Data to know for sure if this is an oversight, expected behavior, or something else, so I was hoping you (or someone else highly knowledgeable about SYB-style generic programming) could help me out here. In particular: 1. Does emitting "dataCast1 f = gcast1 f" for datatypes of kind (k -> *) make sense? Or does it only make sense for types of kind (* -> *)? 2. Is there an alternate way to define dataCast1 that doesn't require the stronger Data context, but instead only requires the more general Typeable context? Ryan S. ----- [1] https://ghc.haskell.org/trac/ghc/ticket/13327 [2] https://ghc.haskell.org/trac/ghc/ticket/4028#comment:5