Hi Reiner,<br><br>It is indeed not strictly necessary to define such helper classes for kind * generic functions. You do need them for kind * -&gt; * functions, though. Also, I think they should always be used because they help keep things separate. If we use an implementation of generics with DataKinds [1], then the helper classes always have a different kind from the user-facing classes.<br>

<br><br>Cheers,<br>Pedro<br><br>[1] <a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving#Kindpolymorphicoverhaul">http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving#Kindpolymorphicoverhaul</a><br>

<br><div class="gmail_quote">On Mon, Mar 12, 2012 at 04:27, Reiner Pope <span dir="ltr">&lt;<a href="mailto:reiner.pope@gmail.com">reiner.pope@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div style="word-wrap:break-word"><div>Hi all,</div><div><br></div>I&#39;ve been playing with GHC&#39;s new generics features (see <a href="http://www.haskell.org/ghc/docs/latest/html/users_guide/generic-programming.html" target="_blank">http://www.haskell.org/ghc/docs/latest/html/users_guide/generic-programming.html</a>). All the documentation I&#39;ve seen suggests creating a &quot;helper class&quot; -- for instance, the GSerialize class in the above link -- on which one defines generic instances. <div>

<br></div><div>It seems to me that this isn&#39;t necessary. For example, here&#39;s the the example from the GHC docs, but without a helper class:</div><div><br></div><div>&gt; -- set the phantom type of Rep to (), to avoid ambiguity</div>

<div>&gt; from0 :: Generic a =&gt; a -&gt; Rep a ()</div><div>&gt; from0 = from</div><div>&gt; </div><div>&gt; data Bit = O | I</div><div>&gt; </div><div>&gt; class Serialize a where</div><div>&gt;   put :: a -&gt; [Bit]</div>

<div>&gt; </div><div>&gt;   default put :: (Generic a, Serialize (Rep a ())) =&gt; a -&gt; [Bit]</div><div>&gt;   put = put . from0</div><div>&gt; </div><div>&gt; instance Serialize (U1 x) where</div><div>&gt;   put U1 = []</div>

<div>&gt; </div><div>&gt; instance (Serialize (a x), Serialize (b x)) =&gt; Serialize ((a :*: b) x) where</div><div>&gt;   put (x :*: y) = put x ++ put y</div><div>&gt; </div><div>&gt; instance (Serialize (a x), Serialize (b x)) =&gt; Serialize ((a :+: b) x) where</div>

<div>&gt;   put (L1 x) = O : put x</div><div>&gt;   put (R1 x) = I : put x</div><div>&gt; </div><div>&gt; instance (Serialize (a x)) =&gt; Serialize (M1 i c a x) where</div><div>&gt;   put (M1 x) = put x</div><div>&gt; </div>

<div>&gt; instance (Serialize a) =&gt; Serialize (K1 i a x) where</div><div>&gt;   put (K1 x) = put x</div><div><br></div><div>Is there a reason to prefer using helper classes? Or perhaps we should update the wiki page (<a href="http://www.haskell.org/haskellwiki/Generics" target="_blank">http://www.haskell.org/haskellwiki/Generics</a>) to avoid using helper classes?</div>

<div><br></div><div>Regards,</div><div>Reiner</div></div><br>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
<br></blockquote></div><br>