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?
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)
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 a
s 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With