Reputation: 4067
Given a data type
data Foo =
Foo1 { foo1Name :: String}
| Foo2 { foo2Name :: String, foo2Age :: Integer }
I would like to be able to extract the Data.Data.DataTypeS
of Foo1
and Foo2
s fields.
I tried
datatype = (undefined :: Foo)
constrs = dataTypeConstrs datatype
foo1 = fromConstrs (head constrs) :: Foo
foo1Fields = gmapQ dataTypeOf foo1
but foo1Fields
will just say that foo1Name
is a Prelude.[]
and not which type parameter is used.
Is it possible to extract type parameters using SYB or should I use another reflection library?
Upvotes: 1
Views: 168
Reputation: 38891
I'm not clear exactly what you're looking to do here? DataTypes are for actually building things. If you just want to get the types, you should be using typeOf.
This works, for example, but it yields TypeReps rather than DataTypes (which, I think, is the right thing)
{-# Language DeriveDataTypeable #-}
import Data.Data
import Data.Typeable
data Foo =
Foo1 { foo1Name :: String}
| Foo2 { foo2Name :: String, foo2Age :: Integer } deriving (Data, Typeable, Show)
datatype = dataTypeOf (undefined :: Foo)
constrs = dataTypeConstrs datatype
fooConstrs = map fromConstr constrs :: [Foo]
foo1Fields = map (gmapQ typeOf) fooConstrs
-- foo1Fields = [[[Char]],[[Char],Integer]]
Upvotes: 2