Most methods I know from lists are actually special cases of some well-known type classes. Some examples of methods and the related type class:
map :: (a -> b) -> [a] -> [b]
and Functor
foldr :: (a -> b -> b) -> b -> [a] -> b
and Foldable
forM :: Monad m => [a] -> (a -> m b) -> m [b]
and Traversable
concat :: [[a]] -> [a]
and Monad
Possibly the list goes on (pardon the pun).
I'm wondering about the "deeper meaning" behind unzip :: [(a, b)] -> ([a], [b])
. Can it be implemented using some famous instances of []
and, e.g., the functor instance of (,a)
? Or some other instances? Ideally, I'd want to have a more abstract function with this type: SomeClass m => unzip :: m (a, b) -> (m a, m b)
. Is there a class that will make this work?
You can simply take first and second projections:
gunzip :: Functor f => f (a, b) -> (f a, f b)
gunzip ps = (fmap fst ps, fmap snd ps)
But note that gunzip
traverses ps
twice unlike the usual zip
for lists, so it's troublesome, because ps
is not garbage collected after the first pass and stays in the memory, which causes memory leaks on big lists.
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