úÎó     portable provisionalEdward Kmett <ekmett@gmail.com> The    s of a given  (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            comonad-0.6.0Control.Comonad Cokleisli runCokleisliComonadextract duplicateextendliftW=>><<==<==>=wfixbase Control.ArrowArrowGHC.Basefmap>>=Monad