I am in need of the following class of functions:
class InterleavedHomomorphic x where
interleaveHomomorphism :: (forall a . f a -> g a) -> x f -> x g
Obviously the name I invented for it is not in any way an official term for anything, and the type class above is not very elegant. Is this a concept that has a name, or even an implementation in some library? Is there some more reasonable way of doing this?
The purpose of this function would be that I have some context f
that annotates some data (Foo
and Bar
are just random example data structures for the sake of this question):
data Foo f = One (f (Bar f)) | Product (f (Foo f)) (f (Foo f))
data Bar f = Zero | Succ (f (Bar f))
I would like to transform the context of the data in a polymorphic way; by only knowing the homomorphism between the contexts and not (necessarily) caring about the data itself. This would be done by providing instance InterleavedHomomorphic Foo
and instance InterleavedHomomorphic Bar
in the example above.
So, assuming
f
andg
are proper functors,forall a. f a -> g a
is a natural transformation. We could make it a bit prettier: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:However, in your case
x f
andx g
are not functors, andx 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 ofx
s with different structures. Each possiblex
, likeFoo
, forms a category with objects likeFoo []
andFoo Maybe
and transformations between them (Foo [] -> Foo Maybe
). YourinterleaveHomomorphism
function "lifts" natural transformations into thesex-morphisms
, just likefmap
"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 likex
.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:
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 aCFunctor
type like this, but a bit cleverer: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.