So, assuming f and g are proper functors, forall a. f a -> g a is a natural transformation. We could make it a bit prettier:

type f ~> g = forall a. f a -> g a

Natural transformations like this let us form a category of Haskell Functors, so what you have is a functor from that to some other category.

Following the steps of normal Haskell Functors, it would perhaps make sense to have x be an endofunctor, mapping Functors to other Functors. This is similar, but not identical, to what you have:

class FFunctor x where ffmap :: (f ~> g) -> (x f ~> x g)

However, in your case x f and x g are not functors, and x f -> x g is a normal function rather than a natural transformation. Still, the pattern is close enough to be intriguing.

With this in mind, it seems that x is still an example of a functor, just between two different categories. It goes from the category of Functors to the category of x s with different structures. Each possible x , like Foo , forms a category with objects like Foo [] and Foo Maybe and transformations between them ( Foo [] -> Foo Maybe ). Your interleaveHomomorphism function "lifts" natural transformations into these x-morphisms , just like fmap "lifts" normal ( a -> b ) functions into functions in the image of the functor ( f a -> f b ).

So yeah: your typeclass is a functor just like Functor , except between two different categories. I don't know of a specific name for it, largely because I don't know a specific name for constructs like x .

More generally, I'm not even sure a specific name would make sense. At this point, we'd probably like a nice generic functor typeclass that go between any two categories. Maybe something like:

class (Category catA, Category catB) => GFunctor f catA catB where gfmap :: catA a b -> catB (f a) (f b)

This probably already exists in a library somewhere.

Unfortunately, this particular approach to defining different functors would require a bunch of extra newtype noise since (->) is already a category. In fact, getting all the types to line up properly is going to be a bit of a pain.

So it's probably easiest just to call it an XFunctor or something. Besides, just imagine the pun potential!

EDIT: It looks like categories provides a CFunctor type like this, but a bit cleverer:

class (Category r, Category s) => CFunctor f r s | f r -> s, f s -> r where cmap :: r a b -> s (f a) (f b)

However, I'm not certain that even this is general enough! I think that we might want it to be more polymorphic over kinds too.