Есть ли способ получить список всех TypeRep
внутри значения, используя общее программирование?
Например, можно ли определить функцию:
typeReps :: (Data a, Typeable a) => a -> [TypeRep]
таким образом, что:
>>> typeReps (1 :: Int, 'a')
[(Int, Char), Int, Char]
>>> typeReps (Foo ['a', 'b'])
[Foo, [Char], Char, Char]
Я пытался
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE RankNTypes #-}
module Example where
import Data.Data
import Data.Typeable
typeReps :: (Data a, Typeable a) => a -> TypeReps a
typeReps a = gfoldl step fcstr a
where
step :: forall d b. (Typeable d, Data d) => TypeReps (d -> b) -> d -> TypeReps b
step tot d = tot <++> typeReps d
fcstr :: forall g . g -> TypeReps g
fcstr g = TypeReps [typeOf a]
Однако это похоже на дублирование типа TypeRep
s в результате:
>>> typeReps ['a']
TypeReps {getTypes = [[Char],Char,[Char]]}
Кроме того, выглядит немного задом наперед, что я не использую g
, но a
в функции fsctr
выше (и я не могу, поскольку я не могу ограничить g
быть Typeable
).
Я не знаю, может ли это быть решено таким образом, и если нет, мне интересно, есть ли другие способы приблизиться к нему.