Search code examples
haskellintrospection

Splitting TypeReps of applied constructors


I'm trying to use Data.Typeable to inspect the component types of a function type. At first, typeRepArgs looks perfect, but I can't seem to get it to work:

Prelude Data.Typeable> typeRepArgs (typeOf2 (id :: Integer -> Integer))
[]
Prelude Data.Typeable> length $ typeRepArgs (typeOf2 (id :: Integer -> Integer))
0

Am I fundamentally misunderstanding how this is supposed to work? Clearly the (->) constructor is being applied to two arguments, so why can't I see them? If I try prodding the function type in the way of dynApply from Data.Dynamic, I get a similarly puzzling result:

Prelude Data.Typeable> funResultTy (typeOf2 (id :: Integer -> Integer)) (typeOf (0 :: Integer))
Nothing

I'm really quite stumped.

If it helps, I'm using GHC 7.0.4.


Solution

  • You need to use the nullary version typeOf

    Prelude Data.Typeable> typeRepArgs $ typeOf (undefined :: Int -> Int)
    [Int,Int]
    

    However, this might not do what you'd expect. It gives the type arguments of the type constructor (->), so for a function with more than one argument you get something like this.

    Prelude Data.Typeable> typeRepArgs $ typeOf (undefined :: Int -> Int -> Int)
    [Int,Int -> Int]
    

    If you want to get the argument types of a curried function, you'll have to recursively deconstruct the function type.