Can we transform a GADT without a given constraint on its constructors to a GADT that does have the said constraint? I want to do this because I want to get a deep-embedding of Arrows and do some interesting things with the representation that (for now) seem to require Typeable
. (One reason)
data DSL a b where
Id :: DSL a a
Comp :: DSL b c -> DSL a b -> DSL a c
-- Other constructors for Arrow(Loop,Apply,etc)
data DSL2 a b where
Id2 :: (Typeable a, Typeable b) => DSL2 a a
Comp2 :: (Typeable a, Typeable b, Typeable c) => DSL2 b c -> DSL2 a b -> DSL2 a c
-- ...
We could try the following from
function but that breaks quickly as we don't have the
Typeable
information for the recursive point
from :: (Typeable a, Typeable b) => DSL a b -> DSL2 a b
from (Id) = Id2
from (Comp g f) = Comp2 (from g) (from f)
So instead we try to capture the transformation in a type class. However, that will break as well as we will be missing the Typeable b
information as b
is an existential.
class From a b where
from :: a -> b
instance (Typeable a, Typeable b) => From (DSL a b) (DSL2 a b) where
from (Id) = Id2
from (Comp g f) = Comp2 (from g) (from f)
Any other suggestions? Ultimately I want to create a deep-embedding of Category
and Arrow
together with Typeable
information on the type parameters. This is so I can use the arrow-syntax to construct a value in my DSL and have fairly standard Haskell code. Maybe I have to resort to Template Haskell?