views:

65

answers:

1

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 Foo2s 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?

+2  A: 

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]]
sclv