<div dir="ltr">Hi Ryan,<div><br></div><div>I can't recall any particular reason to avoid including dataCast1 in the Data instance for poly-kinded datatypes. Have you tried applying the example in #4028 to a poly-kinded datatype? It might be that it was done simply to avoid forcing the kind of the parameter to be *, and hence losing the polymorphism (possibly at the price of losing generic function extension).</div><div><br></div><div>I'm not aware of a way to define dataCast1 without the Data context. Then again, I think it's only used for generic function extension (ext1Q and friends); can you find a way to make that work without the Data constraint?</div><div><br></div><div><br></div><div>Cheers,</div><div>Pedro</div></div><div class="gmail_extra"><br><div class="gmail_quote">On 23 February 2017 at 19:51, Ryan Scott <span dir="ltr"><<a href="mailto:ryan.gl.scott@gmail.com" target="_blank">ryan.gl.scott@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Pedro,<br>
<br>
I'm quite confused by a peculiarity of deriving Data (more info in<br>
Trac #13327 [1]). In particular, if you write this:<br>
<br>
    data T phantom = T<br>
      deriving Data<br>
<br>
Then the derived Data instance is NOT this:<br>
<br>
    instance Typeable phantom => Data (T phantom) where<br>
      ...<br>
<br>
But instead, it's this:<br>
<br>
    instance Data phantom => Data (T phantom) where<br>
      ...<br>
      dataCast1 f = gcast1 f<br>
<br>
The gcast1 part is why it requires the stronger (Data phantom)<br>
context, as you noted in Trac #4028 [2].<br>
<br>
What confuses me, however, is that is apparently does not carry over<br>
to poly-kinded datatypes. For instance, if you write this:<br>
<br>
    data T (phantom :: k) = T<br>
      deriving Data<br>
<br>
Then you do NOT get this instance:<br>
<br>
    instance Data (phantom :: *) => Data (T phantom) where<br>
      ...<br>
      dataCast1 f = gcast1 f<br>
<br>
But instead, you get this instance!<br>
<br>
    instance (Typeable k, Typeable (phantom :: k)) => Data (T phantom) where<br>
      ...<br>
      -- No implementation for dataCast1<br>
<br>
This is quite surprising to me. I'm not knowledgeable enough about<br>
Data to know for sure if this is an oversight, expected behavior, or<br>
something else, so I was hoping you (or someone else highly<br>
knowledgeable about SYB-style generic programming) could help me out<br>
here.<br>
<br>
In particular:<br>
<br>
1. Does emitting "dataCast1 f = gcast1 f" for datatypes of kind (k -><br>
*) make sense? Or does it only make sense for types of kind (* -> *)?<br>
2. Is there an alternate way to define dataCast1 that doesn't require<br>
the stronger Data context, but instead only requires the more general<br>
Typeable context?<br>
<br>
Ryan S.<br>
-----<br>
[1] <a href="https://ghc.haskell.org/trac/ghc/ticket/13327" rel="noreferrer" target="_blank">https://ghc.haskell.org/trac/<wbr>ghc/ticket/13327</a><br>
[2] <a href="https://ghc.haskell.org/trac/ghc/ticket/4028#comment:5" rel="noreferrer" target="_blank">https://ghc.haskell.org/trac/<wbr>ghc/ticket/4028#comment:5</a><br>
</blockquote></div><br></div>