"Transposition" of functors?

category-theory, functor, haskell

Solution

Actually, there is a type class that would support this. It's not included in the standard type class but "representable functors" have this capability.

A representative functor is a functor `F` with two things

- a type `A`

- An isomorphism between `F` and `(->) A`

We could represent this as

 type family ReprObj (f :: * -> *):: *

 class Functor f => Repr f where
   toHom   :: f a -> (ReprObj f -> a)
   fromHom :: (ReprObj f -> a) -> f a

where `toHom . fromHom = fromHom . toHom = id`. An example of a representable functor,

 newtype Pair a = Pair (a, a) deriving Functor
 type instance ReprObj Pair = Bool

 instance Repr Pair where
   toHom (Pair (a, b)) True  = a
   toHom (Pair (a, b)) False = b
   fromHom f = Pair (f True, f False)

Now using this we can derive

swap :: (Functor f, Functor g, Repr f, Repr g) => f (g a) -> g (f a)
swap g = fromHom $ \obj -> fmap ($ obj) hom
   where hom = fmap toHom g

In fact, we can also get a free applicative and monad instance out of representable functors. I detailed how you could do this in a blog post.

Problem

Recently I had to write the following function: ``` mToL :: Maybe [a] -> [Maybe a] mToL Nothing = [] mToL (Just xs) = map Just xs ``` This begged the question whether it is possible to generalize the above to: ``` transposeF :: (Functor f, Functor g) => f (g a) -> g (f a) ``` I guess it only works if there is a way to "collapse" `f (g a)` into `f a`, or is there any other way?

Original source