How to define SYB functions for type extension for tertiary type constructors (ext3)?

128 views Asked by At

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?

1

There are 1 answers

2
sclv On BEST ANSWER

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)) []