[Template-haskell] reifyType function

Andre Pang ozone@algorithm.com.au
Mon, 7 Jul 2003 18:54:45 +1000

Hi all,

Sean Seefried and I managed to implement a reifyType function, which 
we're calling rType since there's already that annoying built-in 
reifyType identifier ;).  It's defined in a ReifyType module which 
looks like thus:

module ReifyType

import Data.Dynamic
import Language.Haskell.THSyntax

class ReifyType a where
    rType :: a -> Typ

instance (ReifyType a, ReifyType b) => ReifyType (a, b) where
    rType (_ :: (t, u)) = Tapp (Tapp (Tcon (Tuple 2)) (rType (undefined 
:: t)))
                          (rType (undefined :: u))

instance ReifyType a => ReifyType [a] where
    rType (_ :: [t]) = Tapp (Tcon List) (rType (undefined :: t))

instance Typeable a => ReifyType a where
    rType (_ :: t) = (Tcon (TconName typeAsString))
          typeAsString = show $ typeOf (undefined :: t)

instance (ReifyType a, ReifyType b) => ReifyType (a->b) where
   rType (_ :: t -> u)
       = (Tapp (rType (undefined :: t)) (rType (undefined :: u)))

An example of how to use it:

18:48 ~/Desktop % ghci -fglasgow-exts -fallow-overlapping-instances 
-fallow-undecidable-instances ReifyType.hs
Loading package base ... linking ... done.
Compiling ReifyType        ( ReifyType.hs, interpreted )
Ok, modules loaded: ReifyType.
*ReifyType> rType Char.toLower
Loading package haskell98 ... linking ... done.
Loading package haskell-src ... linking ... done.
Tapp (Tcon (TconName "Char")) (Tcon (TconName "Char"))
*ReifyType> rType ((+) :: (Int -> Int -> Int))
Tapp (Tcon (TconName "Int")) (Tapp (Tcon (TconName "Int")) (Tcon 
(TconName "Int")))
*ReifyType> rType "foobar"
Tapp (Tcon List) (Tcon (TconName "Char"))

The major restriction is that you're limited to using it on monomorphic 
types (since the typeOf function only works on monomorphic types), but 
otherwise, it seems to work remarkably well.

% Andre Pang : just.your.average.bounty.hunter