<div dir="ltr"><div dir="ltr"><div>Hi and thank you for the answers -- I'll use Data for now since generics seem scary at this point.<br></div><div><br></div><div>Another question :): is there a better way to get the constructor of some partially applied data constructor. My current solution follows (and it works), but I'm wondering if there is a better way? The issue is that I'm feeding `undefined`s until the constructor is saturated and then get the Constr, but it feels like using a loophole (the existence of `undefined`) to achieve the result.  <br></div><div><br></div><div>class GetConstr a where<br>  getConstr :: a -> Constr<br>instance {-# OVERLAPPING #-} (GetConstr b) => GetConstr (a -> b) where<br>  getConstr f = getConstr (f undefined)<br>instance {-# OVERLAPPABLE #-} (Data a) => GetConstr a where<br>  getConstr a = toConstr a<br><br></div></div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Oct 29, 2018 at 11:07 PM Artem Pelenitsyn <<a href="mailto:a.pelenitsyn@gmail.com">a.pelenitsyn@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Oh, didn't know about `one-liner`. This looks v. nice. Thank you!</div><div><br></div><div>-- Artem<br></div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, 29 Oct 2018 at 17:52 Li-yao Xia <<a href="mailto:lysxia@gmail.com" target="_blank">lysxia@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 10/29/18 4:42 PM, Artem Pelenitsyn wrote:<br>
> I don't think there is a point in looking for <br>
> GHC.Generics-based solution, as Data.Data is the exact match for this <br>
> kind of problem.<br>
<br>
Although GHC.Generics has its shortcomings (usage complexity and compile <br>
times), I still find it worthwhile to advocate as a statically-typed <br>
alternative to the dynamically-typed Data.Data for many problems, <br>
including this one.<br>
<br>
Using the one-liner library (which is built around GHC.Generics), the <br>
equivalent line of code is:<br>
<br>
     getSum . gfoldMap @AnyType (const 1) :: T -> Int<br>
<br>
Data.Data is more visible mainly because it comes with a lot of <br>
functionality baked into the standard library, whereas GHC.Generics <br>
provides only a minimal interface and we have to find everything else in <br>
separate packages. However, there is no fundamental reason why one is a <br>
better fit than the other for the task of counting constructor fields.<br>
<br>
Li-yao<br>
<br>
> <br>
> On Mon, 29 Oct 2018 at 16:35 Li-yao Xia <<a href="mailto:lysxia@gmail.com" target="_blank">lysxia@gmail.com</a> <br>
> <mailto:<a href="mailto:lysxia@gmail.com" target="_blank">lysxia@gmail.com</a>>> wrote:<br>
> <br>
>     This maps every field to 1, and folds them together using (+):<br>
> <br>
>           Data.Data.gmapQl (+) 0 (const 1) :: T -> Int<br>
> <br>
>     (There has to be a similarly easy solution using GHC.Generics instead<br>
>     but I can't think of one...)<br>
> <br>
>     Li-yao<br>
> <br>
>     On 10/29/18 2:56 PM, Markus Läll wrote:<br>
>      > Dear list,<br>
>      ><br>
>      > Is it possible te get the number of fields for data constructors<br>
>     for a<br>
>      > plain ADT, i.e something with no record fields? E.g for<br>
>      ><br>
>      > data T = A Int Double | B String (Maybe String)<br>
>      ><br>
>      > it would give 2 for both `A` and `B`.<br>
>      ><br>
>      > For a record it's possible using the `constrFields` function from<br>
>     Data.Data.<br>
>      ><br>
>      > I was trying to follow this tutorial by Christopher Done<br>
>      > <a href="https://chrisdone.com/posts/data-typeable" rel="noreferrer" target="_blank">https://chrisdone.com/posts/data-typeable</a>, and I feel that it<br>
>     must be<br>
>      > possible somehow to get these numbers with the gmap*/gfold*<br>
>     functions,<br>
>      > but the use of them is over my head at the moment.<br>
>      ><br>
>      ><br>
>      > Best,<br>
>      ><br>
>      ><br>
>      ><br>
>      > --<br>
>      > Markus Läll<br>
>      ><br>
>      > _______________________________________________<br>
>      > Haskell-Cafe mailing list<br>
>      > To (un)subscribe, modify options or view archives go to:<br>
>      > <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
>      > Only members subscribed via the mailman list are allowed to post.<br>
>      ><br>
>     _______________________________________________<br>
>     Haskell-Cafe mailing list<br>
>     To (un)subscribe, modify options or view archives go to:<br>
>     <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
>     Only members subscribed via the mailman list are allowed to post.<br>
> <br>
</blockquote></div>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
Only members subscribed via the mailman list are allowed to post.</blockquote></div><br clear="all"><br>-- <br><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">Markus Läll<br></div>