úÎ0v.f"      !portable provisionalEdward Kmett <ekmett@gmail.com> The  " s of a given  FA strong lax symmetric semi-monoidal comonad. As such an instance of  is required to satisfy:  + extract (a <.> b) = extract a (extract b) 'This class is based on ComonadZip from "#The Essence of Dataflow Programming" Mby Tarmo Uustalu and Varmo Vene, but adapted to fit the programming style of Control.Applicative. #. can be seen as a similar law over and above FunctorApply that:  pure (a b) = pure a <.> pure b WTransform a strong lax symmetric semi-monoidal endofunctor into a strong lax symmetric ( monoidal endofunctor by adding a unit. :Wrap Applicatives to be used as a member of FunctorApply .A strong lax symmetric semi-monoidal functor. a .> b = const id  $ a  . b a  . b = const <$ a  . b (There are two ways to define a comonad: I. Provide definitions for  and  satisfying these laws:   extend extract = id  extract . extend f = f - extend f . extend g = extend (f . extend g) !In this case, you may simply set  = . 9These laws are directly analogous to the laws for monads @and perhaps can be made clearer by viewing them as laws stating Dthat Cokleisli composition must be associative, and has extract for a unit:   f =>= extract = f  extract =>= f = f # (f =>= g) =>= h = f =>= (g =>= h) ;II. Alternately, you may choose to provide definitions for , , and  satisfying these laws:   extract . duplicate = id  fmap extract . duplicate = id 7 duplicate . duplicate = fmap duplicate . duplicate 7In this case you may not rely on the ability to define  in  terms of . )You may of course, choose to define both  and . /In that case you must also satisfy these laws:   extend f = fmap f . duplicate  duplicate = extend id " fmap f = extend (f . extract) %These are the default definitions of  and and the definition of  respectively.   extract . fmap f = f . extract   duplicate = extend id 0 fmap (fmap f) . duplicate = duplicate . fmap f   extend f = fmap f . duplicate "A suitable default definition for  for a . # Promotes a function to a comonad. " fmap f = extend (f . extract) % with the arguments swapped. Dual to $ for a %.  in operator form %Right-to-left Cokleisli composition $Left-to-right Cokleisli composition Comonadic fixed point  A variant of  with the arguments reversed. 3Lift a binary function into a comonad with zipping 4Lift a ternary function into a comonad with zipping 3Lift a binary function into a comonad with zipping !4Lift a ternary function into a comonad with zipping &4Only requires a Semigroup, but no such class exists '4Only requires a Semigroup, but no such class exists "  !" !     !(       !"#$%&'()*+,- comonad-0.4.0Control.ComonadbaseGHC.BaseFunctor Data.Functor<$><$fmap Cokleisli runCokleisli ComonadApply WrappedApply WrapApply unwrapApplyWrappedApplicativeunwrapApplicative FunctorApply<.>.><.Comonadextract duplicateextend$>liftW=>><<==<==>=wfix<..>liftF2liftF3liftW2liftW3 Control.ArrowArrowControl.Applicative Applicative>>=Monad$fComonadApply(->)$fComonadApply(,)