lundi 15 avril 2019

Gettting the argument types of a constructor using Data and Typeable

I'm playing around with Haskell's Data and Typeable, and I'm stuck trying to get the arguments of a function without a type variable being available in the context.

Let me clarify what I mean. As long as I have the type variable a quantified like below, I can use fromConstr and obtain a list of DataType or TypeRep as I wish:

constrArgs :: forall a. Data a => Constr -> [DataType]
constrArgs c = gmapQ f (fromConstr c :: a)
  where f :: forall d. Data d => d -> DataType
        f _ = dataTypeOf @d undefined

(I realize the undefined and fromConstr are nontotal but laziness saves us here.)

However, if I try to avoid quantifying a, I can no longer do a type ascription to the result of fromConstr. I wonder if there is a way to write a function with the following type signature:

constrArgs' :: Constr -> [DataType]

My end goal is to write a function that gives a list of lists of DataTypes, a sublist for each constructor, each sublist containing the argument types of that constructor. Using the first version, it's not difficult to write a function with the type signature: (definition elided)

allConstrArgs :: forall a. Data a => [[DataType]]

The problem with this is that I cannot apply allConstrArgs to the results of itself, because there is no way to go from DataType to a type-level value.

So, in order to amend that, can we write a function that has the following type?

allConstrsArgs' :: DataType -> [[DataType]]

I looked around in the base library but I'm failing to see how this can be achieved.





Aucun commentaire:

Enregistrer un commentaire