<div dir="ltr"><div><div>Ah, right. I forgot about this additional wrinkle - GHC only checks the kinds of each type variable at the definition site, not at the site of the Data instance. And Const is poly-kinded, so its second type variable is of kind k, not *, so that's why GHC forgoes defining dataCast2 here. My bad.<br><br></div>So in this case, I suppose it doesn't hurt to relax the second constraint to Typeable. There's the separate issue of whether this is a "correct" Data instance, but GHC won't allow us to derive dataCast2 for the Data (Const a b) instance in the first place, so it's a bit of a moot point.<br><br></div>Ryan S.<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Nov 2, 2016 at 4:17 PM, Index Int <span dir="ltr"><<a href="mailto:vlad.z.4096@gmail.com" target="_blank">vlad.z.4096@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">You propose to add the line<br>
<span class=""><br>
  deriving instance (Data a, Data b) => Data (Const a b)<br>
<br>
</span>to Data.Data in base. I entered it into GHCi with -ddump-deriv and<br>
this is what I got:<br>
<br>
  ghci> deriving instance (Data a, Data b) => Data (Const a b)<br>
<br>
  ==================== Derived instances ====================<br>
  Derived instances:<br>
    instance (Data.Data.Data a_a53b, Data.Data.Data b_a53c) =><br>
             Data.Data.Data (Data.Functor.Const.Const a_a53b b_a53c) where<br>
      Data.Data.gfoldl k_a53f z_a53g (Data.Functor.Const.Const a1_a53h)<br>
        = (z_a53g Data.Functor.Const.Const `k_a53f` a1_a53h)<br>
      Data.Data.gunfold k_a53i z_a53j _<br>
        = k_a53i (z_a53j Data.Functor.Const.Const)<br>
      Data.Data.toConstr (Data.Functor.Const.Const _)<br>
        = Ghci4.$cBHDVlUg6FI9L4iOviG5mer<br>
      Data.Data.dataTypeOf _ = Ghci4.$tBHDVlUg6FI9L4iOviG5mer<br>
<br>
    Ghci4.$tBHDVlUg6FI9L4iOviG5mer :: Data.Data.DataType<br>
    Ghci4.$cBHDVlUg6FI9L4iOviG5mer :: Data.Data.Constr<br>
    Ghci4.$tBHDVlUg6FI9L4iOviG5mer<br>
      = Data.Data.mkDataType "Const" [Ghci4.$<wbr>cBHDVlUg6FI9L4iOviG5mer]<br>
    Ghci4.$cBHDVlUg6FI9L4iOviG5mer<br>
      = Data.Data.mkConstr<br>
          Ghci4.$tBHDVlUg6FI9L4iOviG5mer<br>
          "Const"<br>
          ["getConst"]<br>
          Data.Data.Prefix<br>
<br>
So GHC does not generate a definition for dataCast2 (and it default to<br>
`const Nothing`, I suppose). I tried the same with the constraint<br>
relaxed to Typeable and it worked. Am I missing something?<br>
<div class="HOEnZb"><div class="h5"><br>
On Wed, Nov 2, 2016 at 10:27 PM, Ryan Scott <<a href="mailto:ryan.gl.scott@gmail.com">ryan.gl.scott@gmail.com</a>> wrote:<br>
>> The proposed instance is overconstrained. You only need Typeable for the<br>
>> second argument of Const (because it is phantom).<br>
><br>
> It's a phantom type, but the Data constraint is necessary because the way<br>
> deriving Data works. If  You can read this [1] for an explanation behind<br>
> this design decision. Essentially, if GHC sees that a datatype has two type<br>
> parameters of kind *, then it generates a definition for the dataCast2<br>
> method, which allows for a higher-order version of the cast function. But<br>
> implementing dataCast2 requires that both type parameters be Data instances.<br>
><br>
> A separate question would be whether implementing dataCast2 could be done<br>
> without these Data constraints (and thus allowing the second type parameter<br>
> to only be an instance of Typeable, rather than Data). But that is outside<br>
> my area of expertise; I'd need someone more knowledgeable in the arts of<br>
> Data.Data than I.<br>
><br>
> For now, I am proposing what GHC currently considers to be a canonical Data<br>
> instance for Const. We can revisit the exact instance context details later<br>
> if need be.<br>
><br>
> Ryan S.<br>
> -----<br>
> [1] <a href="https://ghc.haskell.org/trac/ghc/ticket/4028" rel="noreferrer" target="_blank">https://ghc.haskell.org/trac/<wbr>ghc/ticket/4028</a><br>
><br>
> On Wed, Nov 2, 2016 at 3:16 PM, Index Int <<a href="mailto:vlad.z.4096@gmail.com">vlad.z.4096@gmail.com</a>> wrote:<br>
>><br>
>> The proposed instance is overconstrained. You only need Typeable for<br>
>> the second argument of Const (because it is phantom).<br>
>><br>
>> On Wed, Nov 2, 2016 at 7:05 PM, Edward Kmett <<a href="mailto:ekmett@gmail.com">ekmett@gmail.com</a>> wrote:<br>
>> > Definitely an oversight.<br>
>> ><br>
>> > On Wed, Nov 2, 2016 at 11:40 AM, Ryan Scott <<a href="mailto:ryan.gl.scott@gmail.com">ryan.gl.scott@gmail.com</a>><br>
>> > wrote:<br>
>> >><br>
>> >> GHC Trac #12438 [1] exists because there's no Data instance for Const<br>
>> >> in base. I found this quite surprising, since we have Data instances<br>
>> >> for just about every other type combinator out there (Identity, Sum,<br>
>> >> Product, Compose, etc.), but not for Const. The fix for #12438 would<br>
>> >> be quite simple: I propose we add<br>
>> >><br>
>> >>     deriving instance (Data a, Data b) => Data (Const a b)<br>
>> >><br>
>> >> to Data.Data in base. Any objections?<br>
>> >><br>
>> >> Ryan S.<br>
>> >> -----<br>
>> >> [1] <a href="https://ghc.haskell.org/trac/ghc/ticket/12438" rel="noreferrer" target="_blank">https://ghc.haskell.org/trac/<wbr>ghc/ticket/12438</a><br>
>> >> ______________________________<wbr>_________________<br>
>> >> Libraries mailing list<br>
>> >> <a href="mailto:Libraries@haskell.org">Libraries@haskell.org</a><br>
>> >> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/libraries</a><br>
>> ><br>
>> ><br>
>> ><br>
>> > ______________________________<wbr>_________________<br>
>> > Libraries mailing list<br>
>> > <a href="mailto:Libraries@haskell.org">Libraries@haskell.org</a><br>
>> > <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/libraries</a><br>
>> ><br>
><br>
><br>
</div></div></blockquote></div><br></div>