Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Transposition" of functors?

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?

like image 592
Philip Kamenarsky Avatar asked Apr 23 '14 13:04

Philip Kamenarsky


2 Answers

The Traversable typeclass provides the sequence and sequenceA operations, which provide the most general solutions to your problem, but they require different constraints:

sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)

sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
like image 64
Nikita Volkov Avatar answered Dec 03 '22 03:12

Nikita Volkov


This is not possible in general, no. Set f to Const b and g to Identity.

newtype Const b a = Const { getConst :: b }
newtype Identity a = Identity { runIdentity :: a }

These are both obviously functors with their normal instances. transposeF can't work because Const b doesn't supply any as with which to wrap with Identity. So you can't write the transposition function.

On the other hand, this is nice for a whole lot of Functor pairings. The categorical notion is that of the adjoint functor and once you see them, you'll start seeing them everywhere. They're a very powerful notion in their own right.

like image 40
cassandracomar Avatar answered Dec 03 '22 04:12

cassandracomar