Sun 4 May 2008
Kefer asked a question in the comments of my post about (co)monadic (co)strength about Uustalu and Vene's ComonadZip class from p157 of The Essence of Dataflow Programming. The class in question is:
class Comonad w => ComonadZip w where czip :: f a -> f b -> f (a, b)
In response I added Control.Functor.Zip [Source] to my nascent rebundled version of category-extras, which was posted up to hackage earlier today.
Putting aside the dual operation for the moment, we can dispense with the inverse of zip quite simply, for much the same reason that every functor in Haskell is strong, every functor in haskell is unzippable:
unfzip :: Functor f => f (a, b) -> (f a, f b) unfzip = fmap fst &&& fmap snd
On the other hand the question of what Functors are zippable is a little trickier. Allowing for a circular definition between fzip and fzipWith we can start with the following class for which you have to implement at least one of fzip or fzipWith.
class Functor f => Zip f where fzip :: f a -> f b -> f (a, b) fzip = fzipWith (,) fzipWith :: (a -> b -> c) -> f a -> f b -> f c fzipWith f as bs = fmap (uncurry f) (fzip as bs)
Here we set aside the restriction that we only be able to Zip a comonad, and simply require that if the functor in question is a comonad, then it is a "symmetric semi-monoidal comonad", which is to say that zipping and then extracting yields the same result as extracting from each separately. You may note a lot of similarity in the above to the definition for Control.Functor.Zap the Dual functor from the other day.
Now, we can throw ourselves with reckless abandon at the easy cases:
instance Zip Identity where fzipWith f (Identity a) (Identity b) = Identity (f a b) instance Zip [] where fzip = zip fzipWith = zipWith instance Zip Maybe where fzipWith f (Just a) (Just b) = Just (f a b) fzipWith f _ _ = Nothing
But we note that Either causes us to break down, we can't handle the 'mixed' cases of Left and Right cleanly. We can however use the same 'cheat' that makes the Writer Monad work, however, and rely on an instance of Monoid, and leaving the left hand side of the bifunctor unchanged to enable us to define:
instance Monoid a => Zip (Either a) where fzipWith f (Left a) (Left b) = Left (mappend a b) fzipWith f (Right a) (Left b) = Left b fzipWith f (Left a) (Right b) = Left a fzipWith f (Right a) (Right b) = Right (f a b)
and similarly:
instance Monoid a => Zip ((,)a) where fzipWith f (a, c) (b, d) = (mappend a b, f c d)
Unfortunately the instance for ((,)a) is a little less than satisfying, what we really want to say there is that we have a Bifunctor and that it has two parameters that can be zipped together:
class Bifunctor p => Bizip p where bizip :: p a c -> p b d -> p (a,b) (c,d) bizip = bizipWith (,) (,) bizipWith :: (a -> b -> e) -> (c -> d -> f) -> p a c -> p b d -> p e f bizipWith f g as bs = bimap (uncurry f) (uncurry g) (bizip as bs)
Now, we can define a more satisfying instance for (,):
instance Bizip (,) where bizipWith f g (a,b) (c,d) = (f a c, g b d)
However, by its very nature, an instance for Either eludes us.
Now, we can define a "Bifunctor-Functor-Functor Bifunctor" transformer that takes a bifunctor and a pair of functors to wrap it around, and derives a new bifunctor and lift the zippability of each of the parts to the zippability of the whole:
newtype BiffB p f g a b = BiffB { runBiffB :: p (f a) (g b) } instance (Functor f, Bifunctor p, Functor g) => Bifunctor (BiffB p f g) where bimap f g = BiffB . bimap (fmap f) (fmap g) . runBiffB instance (Zip f, Bizip p, Zip g) => Bizip (BiffB p f g) where bizipWith f g as bs = BiffB $ bizipWith (fzipWith f) (fzipWith g) (runBiffB as) (runBiffB bs)
What is interesting about this is that the cofree comonad and free monad can be defined in terms of BiffB given a definition for the fixed point of a bifunctor:
newtype FixB s a = InB { outB :: s a (FixB s a) } instance Bifunctor s => Functor (FixB s) where fmap f = InB . bimap f (fmap f) . outB type Cofree f a = FixB (BiffB (,) Identity f) a type Free f a = FixB (BiffB Either Identity f) a
Then we can define that the fixed point of a zippable bifunctor is a zippable functor:
instance Bizip p => Zip (FixB p) where fzipWith f as bs = InB $ bizipWith f (fzipWith f) (outB as) (outB bs)
Then it immediately follows by the construction for BiffB that every Cofree Comonad of a zippable base functor is Zippable because they are the fixed point of BiffB (,) Identity f. and since (,) is zippable and Identity is zippable, then given f zippable the base bifunctor is zippable, so Cofree f is zippable.
On the other hand, we do not get the same result for the Free Monad, because it is built over BiffB Either Identity f, and Either is not a zippable bifunctor.
We can define some other functors and bifunctors which are zippable, i.e. we can define a "functor-wrapped bifunctor bifunctor":
newtype FunctorB f p a b = FunctorB { runFunctorB :: f (p a b) } liftFunctorB :: Functor f => (p a b -> p c d) -> FunctorB f p a b -> FunctorB f p c d liftFunctorB f = FunctorB . fmap f . runFunctorB instance (Functor f, Bifunctor p) => Bifunctor (FunctorB f p) where bimap f g = liftFunctorB (bimap f g) instance (Zip f, Bizip p) => Bizip (FunctorB f p) where bizipWith f g as bs = FunctorB $ fzipWith (bizipWith f g) (runFunctorB as) (runFunctorB bs)
But the general pattern was set by Either and Maybe. Whenever your functor has a branch you need a way to uniquely determine the way the constant terms combine.
While I think the above yields a pleasingly generic version of zip. I do not believe that I have exhausted the set of possible instances, but yielding them automatically for cofree comonads of zippable functors, and hence for rose trees, streams, was rather nice.
If you have any other instances of note, I would welcome the insight.
May 5th, 2008 at 3:53 pm
your Zip class is almost the same as Applicative:
fzipWith f a b = fmap f a b
Your fzip function is suggested in the Applicative paper as making more sense from a category theory perspective.
This also raises the question of what exactly fzip should do. How do you say that it should ‘zip’? For instance [] is also an applicative functor with the usual Monad-style cartestian product behaviour.
Specifying that unfzip is the inverse of fzip is a good idea. For [] fzip is only a right inverse of unfzip, since you could zip lists of different lengths. The same holds for Maybe: funzip (fzip (Just x) Nothing) /= (Just x, Nothing).
May 5th, 2008 at 4:48 pm
[...] Twan van Laarhoven pointed out that fzip from the other day is a close cousin of applicative chosen to be an inverse of universal construction: unfzip [...]
June 5th, 2008 at 2:34 pm
[...] In an earlier post about the cofree comonad and the expression problem, I used a typeclass defining a form of duality that enables you to let two functors annihilate each other, letting one select the path whenever the other offered up multiple options. To have a shared set of conventions with the material in Zipping and Unzipping Functors, I have since remodeled that class slightly: [...]
June 20th, 2009 at 3:13 pm
fzipWith = liftA2, at least ignoring the inverse law for fzip and funzip as you seem to have for [] (where you chose the ZipList semantics) and Maybe. Perhaps the [] and Maybe instances for Zip should be removed, and instances for known Applicatives which follow the inverse law should be added?
June 22nd, 2009 at 4:59 pm
@Jake
I almost agree. I’ve had people point out the connection to Applicative on several occasions before, but it falters slightly.
There is no requirement for the existence of unit, so your functor need not be pointed. This permits the class of zippable functors to be slightly wider than the class of applicative functors.
Secondly the particular near-applicative operation is selected explicitly so it will be a left inverse to unzip.
fzip . unfzip = id
Since that should hold for any functor to claim to be a member of Zip the definition is narrower than that of Applicative. Using list monad semantics for fzip on [] would fail this law.
So Zip is neither a superclass nor a subclass of Applicative.
That, at least, was my justification for a zippable functor as an independent concept; I may not have fully articulated the justification back when i wrote this article.
February 22nd, 2012 at 3:29 pm
I also want liftPair in Applicative
September 23rd, 2022 at 4:29 am
Viagra from canada https://500px.com/p/skulogovid/?view=groups...
Kudos. Lots of knowledge.
…
September 23rd, 2022 at 8:33 am
buy viagra usa https://500px.com/p/bersavahi/?view=groups...
Amazing quite a lot of superb data….
September 24th, 2022 at 1:38 am
Viagra generique https://reallygoodemails.com/canadianpharmaceuticalsonlineusa...
Seriously tons of amazing information….
September 24th, 2022 at 5:15 am
Viagra from canada https://www.provenexpert.com/canadian-pharmaceuticals-online-usa/...
Nicely put, Cheers….
September 24th, 2022 at 10:22 am
Viagra purchasing https://sanangelolive.com/members/pharmaceuticals...
Regards, Excellent information….
September 26th, 2022 at 9:19 am
5 mg viagra coupon printable https://melaninterest.com/user/canadian-pharmaceuticals-online/?view=likes...
Amazing postings. Cheers….
September 26th, 2022 at 1:21 pm
Viagra prices https://haikudeck.com/canadian-pharmaceuticals-online-personal-presentation-827506e003...
You explained it superbly!…
September 26th, 2022 at 5:30 pm
Viagra vs viagra https://buyersguide.americanbar.org/profile/420642/0...
Nicely put. Cheers….
September 27th, 2022 at 1:12 am
Viagra 5 mg funziona https://experiment.com/users/canadianpharmacy...
You actually stated this very well….
September 27th, 2022 at 7:08 am
Viagra generique https://slides.com/canadianpharmaceuticalsonline...
Very good write ups. Thank you!…
September 27th, 2022 at 10:48 am
Viagra tablets australia https://challonge.com/esapenti...
Very well expressed of course! ….
September 27th, 2022 at 3:15 pm
Viagra vs viagra vs levitra https://challonge.com/gotsembpertvil...
Thank you. Loads of content.
…
September 28th, 2022 at 5:00 am
Discount viagra https://challonge.com/citlitigolf...
Regards! I enjoy this….
September 28th, 2022 at 8:33 am
Buy viagra https://order-stromectol-over-the-counter.estranky.cz/clanky/order-stromectol-over-the-counter.html...
Amazing tons of wonderful tips….
September 28th, 2022 at 3:00 pm
stromectol for sale https://soncheebarxu.estranky.cz/clanky/stromectol-for-head-lice.html...
You said that really well!…
September 29th, 2022 at 4:32 am
buy ivermectin https://lehyriwor.estranky.sk/clanky/stromectol-cream.html...
Thank you! Ample write ups!
…
September 29th, 2022 at 2:45 pm
Viagra for daily use https://inflavnena.zombeek.cz/...
Superb write ups. Kudos!…
September 30th, 2022 at 9:01 am
canadian pharmacy meds https://www.myscrsdirectory.com/profile/421708/0...
You said this exceptionally well….
September 30th, 2022 at 4:13 pm
Viagra coupon https://supplier.ihrsa.org/profile/421717/0...
Fantastic postings. Thanks….
October 1st, 2022 at 6:34 am
Viagra cost https://wefbuyersguide.wef.org/profile/421914/0...
Wow plenty of awesome tips….
October 1st, 2022 at 10:35 am
Viagra levitra https://legalmarketplace.alanet.org/profile/421920/0...
Nicely put, Appreciate it….
October 2nd, 2022 at 4:12 am
Viagra generika https://moaamein.nacda.com/profile/422018/0...
Fantastic facts. Thanks a lot….
October 2nd, 2022 at 8:38 am
canadian government approved pharmacies https://www.audiologysolutionsnetwork.org/profile/422019/0...
Well spoken certainly. ….
October 2nd, 2022 at 11:55 am
Tadalafil https://network.myscrs.org/profile/422020/0...
Terrific tips. Regards….
October 3rd, 2022 at 5:41 am
Viagra generic https://sanangelolive.com/members/canadianpharmaceuticalsonlineusa...
Helpful advice. Cheers!…
October 3rd, 2022 at 9:06 am
Viagra generika https://sanangelolive.com/members/girsagerea...
You actually revealed it very well….
October 4th, 2022 at 7:52 am
Viagra or viagra https://www.ecosia.org/search?q=“My Canadian Pharmacy – Extensive Assortment of Medications – 2022″…
Wonderful stuff. Appreciate it!…
October 4th, 2022 at 11:44 am
no 1 canadian pharcharmy online https://www.mojomarketplace.com/user/Canadianpharmaceuticalsonline-EkugcJDMYH...
Very good facts. Many thanks….
October 4th, 2022 at 4:01 pm
How does viagra work https://seedandspark.com/user/canadian-pharmaceuticals-online...
Superb information, Kudos!…
October 5th, 2022 at 9:03 am
Interactions for viagra https://www.giantbomb.com/profile/canadapharmacy/blog/canadian-pharmaceuticals-online/265652/...
Nicely put. Thank you….
October 5th, 2022 at 12:54 pm
drugs for sale https://feeds.feedburner.com/bing/Canadian-pharmaceuticals-online...
You actually expressed that effectively!…
October 5th, 2022 at 5:41 pm
buy viagra now https://search.gmx.com/web/result?q=“My Canadian Pharmacy – Extensive Assortment of Medications – 2022″…
Wow tons of superb advice….
October 6th, 2022 at 2:47 am
Viagra 5mg prix https://search.seznam.cz/?q=“My Canadian Pharmacy – Extensive Assortment of Medications – 2022″…
You actually reported this superbly….
October 6th, 2022 at 10:45 am
Generic viagra …
Nicely put. Thanks!…
October 6th, 2022 at 4:42 pm
Buy viagra online https://swisscows.com/en/web?query=“My Canadian Pharmacy – Extensive Assortment of Medications – 2022″…
Superb content. Thank you….
October 7th, 2022 at 4:02 am
Canadian viagra https://www.dogpile.com/serp?q=“My Canadian Pharmacy – Extensive Assortment of Medications – 2022″…
Regards. Very good information!…
October 7th, 2022 at 11:13 am
Viagra online …
Amazing write ups, With thanks….
October 9th, 2022 at 5:48 am
Viagra 20mg …
Nicely put. Regards….
October 9th, 2022 at 10:54 am
Viagra 20mg https://results.excite.com/serp?q=“My Canadian Pharmacy – Extensive Assortment of Medications – 2022″…
You explained that exceptionally well!…
October 9th, 2022 at 3:24 pm
Viagra cost https://www.infospace.com/serp?q=“My Canadian Pharmacy – Extensive Assortment of Medications – 2022″…
You actually stated this effectively!…
October 10th, 2022 at 7:40 am
Viagra tablets https://headwayapp.co/canadianppharmacy-changelog...
Regards, A good amount of facts!
…
October 11th, 2022 at 5:39 am
Viagra tablets https://results.excite.com/serp?q=“My Canadian Pharmacy – Extensive Assortment of Medications – 2022″…
Thanks, Ample data!
…
October 11th, 2022 at 11:02 am
Viagra canada https://canadianpharmaceuticalsonline.as.me/schedule.php...
You explained it adequately!…
October 13th, 2022 at 12:58 pm
buy viagra online usa https://feeds.feedburner.com/bing/stromectolnoprescription...
Superb stuff. Thank you!…
October 14th, 2022 at 5:24 am
Viagra generique https://reallygoodemails.com/orderstromectoloverthecounterusa...
Thank you! Excellent information….