One possibility would be to create a Typeable
instance yourself. I struggled a bit with creating TyCon
for Container
, maybe there is a better way how to do it:
{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE DeriveDataTypeable #-}
module Main where
import Data.Dynamic
import Data.Typeable
data Tree a = EmptyTree | Node a (Tree a) (Tree a)
deriving (Show, Read, Eq, Typeable)
-- copy a representation of a type constructor from
-- an existing representation
copyTyCon :: Typeable a => a -> String -> TyCon
copyTyCon x = mkTyCon3 (tyConPackage tc) (tyConModule tc)
where tc = typeRepTyCon (typeOf x)
data Dummy = Dummy -- just to get package/module names for Container
deriving (Typeable)
data Container a b = Container { contField :: b a }
deriving (Show)
instance (Typeable a, Typeable1 f) => Typeable (Container a f) where
typeOf (Container x) = mkTyConApp (copyTyCon Dummy "Container")
[typeOf (undefined :: a), typeOf1 x]
result = Container { contField = Node 'a' EmptyTree EmptyTree }
main = do
print $ typeOf result
print result
Take it with a grain of salt, I'm not very experienced with Typeable
.