In the Scrap Your Boilerplate package, in Data.Generics.Aliases
, there are functions to allow type extension for unary, and binary type constructors. In particular, there are definitions for ext1
and ext2
.
Now, ext1
and ext2
are defined in terms of dataCast1
, and dataCast2
, which are part of the Data
type class, and are usually defined by the DeriveDataTypeable
machinery. But, there's no dataCast3
, so I don't see an easy way to define ext3
.
Is it possible to define ext3
, and if so, how?
I'm pretty sure this isn't sufficient. But it feels darn close.
ext3 :: (Data a, Typeable3 t)
=> c a
-> (forall d1 d2 d3. c (t d1 d2 d3))
-> c a
ext3 def ext = maybe def (id) (gcast3' ext)
gcast3' :: (Typeable3 t, Data a) => c (t f g h) -> Maybe (c a)
gcast3' x = r
where
r = if typeOf3 (getArg x) == typeOf3' (getArg (fromJust r))
then Just $ unsafeCoerce x
else Nothing
getArg :: c x -> x
getArg = undefined
typeOf3' z = mkTyConApp (typeRepTyCon (typeOf z)) []