úÎ0:-Ž     portable provisionalEdward Kmett <ekmett@gmail.com> TrustworthyThe   s of a given    ComonadApply is to Comonad like  Applicative is to Monad. JMathematically, it is a strong lax symmetric semi-monoidal comonad on the  category Hask' of Haskell types. That it to say that w is a strong lax O symmetric semi-monoidal functor on Hask, where both extract and duplicate are - symmetric monoidal natural transformations. Laws:  ) (.) <$> u <@> v <@> w = u <@> (v <@> w) + extract (p <@> q) = extract p (extract q) = duplicate (p <@> q) = (<@>) <$> duplicate p <@> duplicate q FIf our type is both a ComonadApply and Applicative we further require   (<*>) = (<@>) "Finally, if you choose to define ( ) and ( ), the results of your . definitions should match the following laws:  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 = liftW f = extend (f . extract) $Comonadic fixed point à la Menendez #Comonadic fixed point à la Orchard % with the arguments swapped. Dual to  for a .  in operator form $Right-to-left Cokleisli composition $Left-to-right Cokleisli composition  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 CReplace the contents of a functor uniformly with a constant value. -  !"#$%&'()*+,-./0123   %   !"#$%&'()*+,-./01234       !"#$%&'()*+,-./0123456789 comonad-3.1Control.ComonadbaseGHC.BasefmapFunctor Data.Functor<$><$ Cokleisli runCokleisli ComonadApply<@>@><@Comonadextract duplicateextendliftWwfixcfix=>><<==<==>=<@@>liftW2liftW3$> Control.ArrowArrow>>=MonadcokleisliTyCon$fMonadCokleisli$fApplicativeCokleisli$fFunctorCokleisli$fArrowLoopCokleisli$fArrowChoiceCokleisli$fArrowApplyCokleisli$fArrowCokleisli$fCategoryCokleisli$fTypeable2Cokleisli$fComonadApplyTree$fComonadApplyIdentityT$fComonadApplyIdentity$fComonadApply(->)$fComonadApplyNonEmpty$fComonadApply(,)$fComonadNonEmpty $fComonadTree$fComonadIdentityT$fComonadTagged$fComonadIdentity $fComonad(->) $fComonad(,)