packages feed

comonad 0.1.1 → 0.3.0

raw patch · 2 files changed

+61/−62 lines, 2 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Control.Comonad: wzip :: ComonadZip w => w a -> w b -> w (a, b)

Files

Control/Comonad.hs view
@@ -16,8 +16,6 @@   -- * Functor and Comonad     Functor(..)   , Comonad(..)-  , ComonadZip(..)-  , Cokleisli(..)   -- * Functions    -- ** Naming conventions@@ -28,7 +26,6 @@   , (=<=)   -- :: Comonad w => (w b -> c) -> (w a -> b) -> w a -> c   , (=>>)   -- :: Comonad w => w a -> (w a -> b) -> w b   , (<<=)   -- :: Comonad w => (w a -> b) -> w a -> w b-  , (<..>)  -- :: ComonadZip w => w a -> w (a -> b) -> w b    -- * Fixed points and folds   , wfix    -- :: Comonad w => w (w a -> a) -> a@@ -36,19 +33,25 @@    -- ** Comonadic lifting    , liftW   -- :: Comonad w => (a -> b) -> w a -> w b++  -- * Comonads with Zipping+  , ComonadZip(..)+  , (<..>)  -- :: ComonadZip w => w a -> w (a -> b) -> w b   , liftW2  -- :: ComonadZip w => (a -> b -> c) -> w a -> w b -> w c   , liftW3  -- :: ComonadZip w => (a -> b -> c -> d) -> w a -> w b -> w c -> w d-  , wzip    -- :: ComonadZip w => w a -> w b -> w (a, b) +  -- * Cokleisli Arrows+  , Cokleisli(..)   ) where  import Prelude hiding (id, (.))+import Control.Applicative import Control.Arrow import Control.Category+import Control.Monad.Trans.Identity import Data.Functor-import Data.Monoid import Data.Functor.Identity-import Control.Monad.Trans.Identity+import Data.Monoid  infixl 1 =>>  infixr 1 <<=, =<=, =>= @@ -57,37 +60,51 @@ {-| There are two ways to define a comonad: -I. Provide definitions for 'fmap', 'extract', and 'duplicate'+I. Provide definitions for 'extract' and 'extend' satisfying these laws: -> extract . duplicate      == id-> fmap extract . duplicate == id-> duplicate . duplicate    == fmap duplicate . duplicate+> extend extract      = id+> extract . extend f  = f+> extend f . extend g = extend (f . extend g) -II. Provide definitions for 'extract' and 'extend'-satisfying these laws:+In this case, you may simply set 'fmap' = 'liftW'. -> extend extract      == id-> extract . extend f  == f-> extend f . extend g == extend (f . extend g)+These laws are directly analogous to the laws for monads+and perhaps can be made clearer by viewing them as laws stating+that Cokleisli composition must be associative, and has extract for+a unit: -('fmap' cannot be defaulted, but a comonad which defines-'extend' may simply set 'fmap' equal to 'liftW'.)+> f =>= extract   = f+> extract =>= f   = f+> (f =>= g) =>= h = f =>= (g =>= h) -A comonad providing definitions for 'extend' /and/ 'duplicate',-must also satisfy these laws:+II. Alternately, you may choose to provide definitions for 'fmap',+'extract', and 'duplicate' satisfying these laws: -> extend f  == fmap f . duplicate-> duplicate == extend id-> fmap f    == extend (f . extract)+> extract . duplicate      = id+> fmap extract . duplicate = id+> duplicate . duplicate    = fmap duplicate . duplicate -(The first two are the defaults for 'extend' and 'duplicate',-and the third is the definition of 'liftW'.)+In this case you may not rely on the ability to define 'fmap' in +terms of 'liftW'.++You may of course, choose to define both 'duplicate' /and/ 'extend'. +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 'extend' and'duplicate' and +the 'default' definition of 'liftW' respectively. -}  class Functor w => Comonad w where+  -- | aka coreturn   extract:: w a -> a+  -- | aka cojoin   duplicate :: w a -> w (w a)+  -- | aka cobind   extend :: (w a -> b) -> w a -> w b    extend f = fmap f . duplicate@@ -162,69 +179,50 @@  As a symmetric semi-monoidal comonad, an instance of ComonadZip is required to satisfy: -> extract (wzip a b) = (extract a, extract b)--By extension, the following law must also hold:- > extract (a <.> b) = extract a (extract b) -Minimum definition: '<.>'+Minimal definition: '<.>' -Based on the ComonadZip from "The Essence of Dataflow Programming" -by Tarmo Uustalu and Varmo Vene, but adapted to fit the conventions of -Control.Monad and to provide a similar programming style to -that of Control.Applicative. +Based on the ComonadZip from \"The Essence of Dataflow Programming\" +by Tarmo Uustalu and Varmo Vene, but adapted to fit the programming style of+Control.Applicative.   -} class Comonad w => ComonadZip w where-  -- | -  -- > (<.>) = liftW2 id   (<.>) :: w (a -> b) -> w a -> w b--  -- |-  -- > (.>) = liftW2 (const id)   (.>) :: w a -> w b -> w b-  (.>) = liftW2 (const id)--  -- |-  -- > (<.) = liftW2 const   (<.) :: w a -> w b -> w a-  (<.) = liftW2 const++  a .> b = const id <$> a <.> b+  a <. b = const    <$> a <.> b    instance Monoid m => ComonadZip ((,)m) where-  ~(m, a) <.> ~(n, b) = (m `mappend` n, a b)+  (<.>) = (<*>)  instance Monoid m => ComonadZip ((->)m) where-  g <.> h = \m -> (g m) (h m)+  (<.>) = (<*>)  instance ComonadZip Identity where-  Identity a <.> Identity b = Identity (a b)+  (<.>) = (<*>)  instance ComonadZip w => ComonadZip (IdentityT w) where   IdentityT wa <.> IdentityT wb = IdentityT (wa <.> wb) +-- | A variant of '<.>' with the arguments reversed. (<..>) :: ComonadZip w => w a -> w (a -> b) -> w b-(<..>) = liftW2 (flip ($))+(<..>) = liftW2 (flip id) {-# INLINE (<..>) #-} --- |--- > wzip wa wb = (,) <$> wa <.> wb--- > wzip = liftW2 (,) --- --- Called 'czip' in "Essence of Dataflow Programming"-wzip :: ComonadZip w => w a -> w b -> w (a, b)-wzip = liftW2 (,)-{-# INLINE wzip #-}-+-- | Lift a binary function into a comonad with zipping liftW2 :: ComonadZip w => (a -> b -> c) -> w a -> w b -> w c liftW2 f a b = f <$> a <.> b {-# INLINE liftW2 #-} +-- | Lift a ternary function into a comonad with zipping liftW3 :: ComonadZip w => (a -> b -> c -> d) -> w a -> w b -> w c -> w d liftW3 f a b c = f <$> a <.> b <.> c {-# INLINE liftW3 #-} - -- | The 'Cokleisli' 'Arrow's of a given 'Comonad' newtype Cokleisli w a b = Cokleisli { runCokleisli :: w a -> b } @@ -247,7 +245,7 @@  instance ComonadZip d => ArrowLoop (Cokleisli d) where   loop (Cokleisli f) = Cokleisli (fst . wfix . extend f') where -    f' wa = f . wzip wa . fmap snd+    f' wa wb = f ((,) <$> wa <.> (snd <$> wb))  instance Functor (Cokleisli w a) where   fmap f (Cokleisli g) = Cokleisli (f . g)@@ -265,8 +263,8 @@   The monad type constructor @w@ is added to function results   (modulo currying) and nowhere else.  So, for example,  ->  filter  ::                (a ->   Bool) -> [a] ->   [a]->  filterW :: (Comonad w) => (w a -> Bool) -> w [a] -> [a]+>  filter  ::              (a ->   Bool) -> [a] ->   [a]+>  filterW :: Comonad w => (w a -> Bool) -> w [a] -> [a]  * A prefix \'@w@\' generalizes an existing function to a comonadic form.   Thus, for example: @@ -274,6 +272,7 @@ >  fix  :: (a -> a) -> a >  wfix :: w (w a -> a) -> a -When ambiguous, consistency with existing Control.Monad combinators supercedes other naming considerations.+When ambiguous, consistency with existing Control.Monad combinator naming +supercedes these rules (e.g. 'liftW')  -}
comonad.cabal view
@@ -1,6 +1,6 @@ name:          comonad category:      Control, Comonads-version:       0.1.1+version:       0.3.0 license:       BSD3 cabal-version: >= 1.2 license-file:  LICENSE