Hi and thank you for the answers -- I'll use Data for now since generics seem scary at this point.

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. 

class GetConstr a where
  getConstr :: a -> Constr
instance {-# OVERLAPPING #-} (GetConstr b) => GetConstr (a -> b) where
  getConstr f = getConstr (f undefined)
instance {-# OVERLAPPABLE #-} (Data a) => GetConstr a where
  getConstr a = toConstr a


On Mon, Oct 29, 2018 at 11:07 PM Artem Pelenitsyn <a.pelenitsyn@gmail.com> wrote:
Oh, didn't know about `one-liner`. This looks v. nice. Thank you!

-- Artem

On Mon, 29 Oct 2018 at 17:52 Li-yao Xia <lysxia@gmail.com> wrote:
On 10/29/18 4:42 PM, Artem Pelenitsyn wrote:
> I don't think there is a point in looking for
> GHC.Generics-based solution, as Data.Data is the exact match for this
> kind of problem.

Although GHC.Generics has its shortcomings (usage complexity and compile
times), I still find it worthwhile to advocate as a statically-typed
alternative to the dynamically-typed Data.Data for many problems,
including this one.

Using the one-liner library (which is built around GHC.Generics), the
equivalent line of code is:

     getSum . gfoldMap @AnyType (const 1) :: T -> Int

Data.Data is more visible mainly because it comes with a lot of
functionality baked into the standard library, whereas GHC.Generics
provides only a minimal interface and we have to find everything else in
separate packages. However, there is no fundamental reason why one is a
better fit than the other for the task of counting constructor fields.

Li-yao

>
> On Mon, 29 Oct 2018 at 16:35 Li-yao Xia <lysxia@gmail.com
> <mailto:lysxia@gmail.com>> wrote:
>
>     This maps every field to 1, and folds them together using (+):
>
>           Data.Data.gmapQl (+) 0 (const 1) :: T -> Int
>
>     (There has to be a similarly easy solution using GHC.Generics instead
>     but I can't think of one...)
>
>     Li-yao
>
>     On 10/29/18 2:56 PM, Markus Läll wrote:
>      > Dear list,
>      >
>      > Is it possible te get the number of fields for data constructors
>     for a
>      > plain ADT, i.e something with no record fields? E.g for
>      >
>      > data T = A Int Double | B String (Maybe String)
>      >
>      > it would give 2 for both `A` and `B`.
>      >
>      > For a record it's possible using the `constrFields` function from
>     Data.Data.
>      >
>      > I was trying to follow this tutorial by Christopher Done
>      > https://chrisdone.com/posts/data-typeable, and I feel that it
>     must be
>      > possible somehow to get these numbers with the gmap*/gfold*
>     functions,
>      > but the use of them is over my head at the moment.
>      >
>      >
>      > Best,
>      >
>      >
>      >
>      > --
>      > Markus Läll
>      >
>      > _______________________________________________
>      > Haskell-Cafe mailing list
>      > To (un)subscribe, modify options or view archives go to:
>      > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>      > Only members subscribed via the mailman list are allowed to post.
>      >
>     _______________________________________________
>     Haskell-Cafe mailing list
>     To (un)subscribe, modify options or view archives go to:
>     http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>     Only members subscribed via the mailman list are allowed to post.
>
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.


--
Markus Läll