packages feed

comonad 1.1.1.6 → 3.0

raw patch · 3 files changed

+215/−247 lines, 3 filesdep ~semigroupsPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: semigroups

API changes (from Hackage documentation)

- Control.Comonad: class Functor w => Extend w where extend f = fmap f . duplicate duplicate = extend id
- Control.Comonad: instance (Semigroup m, Monoid m) => Comonad ((->) m)
- Data.Functor.Extend: (<<=) :: Extend w => (w a -> b) -> w a -> w b
- Data.Functor.Extend: (=<=) :: Extend w => (w b -> c) -> (w a -> b) -> w a -> c
- Data.Functor.Extend: (=>=) :: Extend w => (w a -> b) -> (w b -> c) -> w a -> c
- Data.Functor.Extend: (=>>) :: Extend w => w a -> (w a -> b) -> w b
- Data.Functor.Extend: class Functor w => Extend w where extend f = fmap f . duplicate duplicate = extend id
- Data.Functor.Extend: duplicate :: Extend w => w a -> w (w a)
- Data.Functor.Extend: extend :: Extend w => (w a -> b) -> w a -> w b
- Data.Functor.Extend: instance Extend ((,) e)
- Data.Functor.Extend: instance Extend (Either a)
- Data.Functor.Extend: instance Extend Identity
- Data.Functor.Extend: instance Extend Maybe
- Data.Functor.Extend: instance Extend NonEmpty
- Data.Functor.Extend: instance Extend Seq
- Data.Functor.Extend: instance Extend Tree
- Data.Functor.Extend: instance Extend []
- Data.Functor.Extend: instance Extend w => Extend (IdentityT w)
- Data.Functor.Extend: instance Semigroup m => Extend ((->) m)
+ Control.Comonad: ($>) :: Functor f => f a -> b -> f b
+ Control.Comonad: (<$) :: Functor f => a -> f b -> f a
+ Control.Comonad: (<$>) :: Functor f => (a -> b) -> f a -> f b
+ Control.Comonad: (<@) :: ComonadApply w => w a -> w b -> w a
+ Control.Comonad: (<@>) :: ComonadApply w => w (a -> b) -> w a -> w b
+ Control.Comonad: (<@@>) :: ComonadApply w => w a -> w (a -> b) -> w b
+ Control.Comonad: (@>) :: ComonadApply w => w a -> w b -> w b
+ Control.Comonad: cfix :: Comonad w => (w a -> a) -> w a
+ Control.Comonad: class Comonad w => ComonadApply w where a @> b = const id <$> a <@> b a <@ b = const <$> a <@> b
+ Control.Comonad: class Functor (f :: * -> *)
+ Control.Comonad: fmap :: Functor f => (a -> b) -> f a -> f b
+ Control.Comonad: instance ComonadApply Identity
+ Control.Comonad: instance ComonadApply NonEmpty
+ Control.Comonad: instance ComonadApply Tree
+ Control.Comonad: instance ComonadApply w => ArrowLoop (Cokleisli w)
+ Control.Comonad: instance ComonadApply w => ComonadApply (IdentityT w)
+ Control.Comonad: instance Monoid m => Comonad ((->) m)
+ Control.Comonad: instance Monoid m => ComonadApply ((->) m)
+ Control.Comonad: instance Semigroup m => ComonadApply ((,) m)
+ Control.Comonad: liftW2 :: ComonadApply w => (a -> b -> c) -> w a -> w b -> w c
+ Control.Comonad: liftW3 :: ComonadApply w => (a -> b -> c -> d) -> w a -> w b -> w c -> w d
- Control.Comonad: (<<=) :: Extend w => (w a -> b) -> w a -> w b
+ Control.Comonad: (<<=) :: Comonad w => (w a -> b) -> w a -> w b
- Control.Comonad: (=<=) :: Extend w => (w b -> c) -> (w a -> b) -> w a -> c
+ Control.Comonad: (=<=) :: Comonad w => (w b -> c) -> (w a -> b) -> w a -> c
- Control.Comonad: (=>=) :: Extend w => (w a -> b) -> (w b -> c) -> w a -> c
+ Control.Comonad: (=>=) :: Comonad w => (w a -> b) -> (w b -> c) -> w a -> c
- Control.Comonad: (=>>) :: Extend w => w a -> (w a -> b) -> w b
+ Control.Comonad: (=>>) :: Comonad w => w a -> (w a -> b) -> w b
- Control.Comonad: class Extend w => Comonad w
+ Control.Comonad: class Functor w => Comonad w where duplicate = extend id extend f = fmap f . duplicate
- Control.Comonad: duplicate :: Extend w => w a -> w (w a)
+ Control.Comonad: duplicate :: Comonad w => w a -> w (w a)
- Control.Comonad: extend :: Extend w => (w a -> b) -> w a -> w b
+ Control.Comonad: extend :: Comonad w => (w a -> b) -> w a -> w b

Files

Control/Comonad.hs view
@@ -2,7 +2,7 @@ ----------------------------------------------------------------------------- -- | -- Module      :  Control.Comonad--- Copyright   :  (C) 2008-2011 Edward Kmett,+-- Copyright   :  (C) 2008-2012 Edward Kmett, --                (C) 2004 Dave Menendez -- License     :  BSD-style (see the file LICENSE) --@@ -11,93 +11,254 @@ -- Portability :  portable -- -----------------------------------------------------------------------------module Control.Comonad ( -  -- * Extendable Functors-    Extend(..)+module Control.Comonad (+  -- * Comonads+    Comonad(..)+  , liftW     -- :: Comonad w => (a -> b) -> w a -> w b+  , wfix      -- :: Comonad w => w (w a -> a) -> a+  , cfix      -- :: Comonad w => (w a -> a) -> w a   , (=>=)   , (=<=)   , (<<=)   , (=>>)-  -- * Comonads-  -- $definition-  , Comonad(..)-  , liftW     -- :: Comonad w => (a -> b) -> w a -> w b-  , wfix      -- :: Comonad w => w (w a -> a) -> a-+  -- * Combining Comonads+  , ComonadApply(..)+  , (<@@>)    -- :: ComonadApply w => w a -> w (a -> b) -> w b+  , liftW2    -- :: ComonadApply w => (a -> b -> c) -> w a -> w b -> w c+  , liftW3    -- :: ComonadApply w => (a -> b -> c -> d) -> w a -> w b -> w c -> w d   -- * Cokleisli Arrows   , Cokleisli(..)+  -- * Functors+  , Functor(..)+  , (<$>)     -- :: Functor f => (a -> b) -> f a -> f b+  , ($>)      -- :: Functor f => f a -> b -> f b   ) where -import Prelude hiding (id, (.))+-- import _everything_ import Control.Applicative import Control.Arrow import Control.Category+import Control.Monad (ap)+import Control.Monad.Instances import Control.Monad.Trans.Identity import Data.Functor.Identity-import Data.Functor.Extend-import Data.List.NonEmpty-import Data.Typeable-import Data.Semigroup+import Data.List.NonEmpty hiding (map)+import Data.Semigroup hiding (Product) import Data.Tree+import Prelude hiding (id, (.))+import Control.Monad.Fix+import Data.Typeable -{- | $definition -}+infixl 4 <@, @>, <@@>, <@>, $>+infixl 1 =>>+infixr 1 <<=, =<=, =>= -class Extend w => Comonad w where-  -- | +{- |++There are two ways to define a comonad:++I. Provide definitions for 'extract' and 'extend'+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 'fmap' = 'liftW'.++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:++> f =>= extract   = f+> extract =>= f   = f+> (f =>= g) =>= h = f =>= (g =>= h)++II. Alternately, you may choose to provide definitions for 'fmap',+'extract', and 'duplicate' satisfying these laws:++> extract . duplicate      = id+> fmap extract . duplicate = id+> duplicate . duplicate    = fmap duplicate . duplicate++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 definition of 'liftW' respectively.++-}++class Functor w => Comonad w where+  -- |   -- > extract . fmap f = f . extract-  extract   :: w a -> a+  extract :: w a -> a --- | A suitable default definition for 'fmap' for a 'Comonad'. --- Promotes a function to a comonad.------ > fmap f    = extend (f . extract)-liftW :: Comonad w => (a -> b) -> w a -> w b-liftW f = extend (f . extract)-{-# INLINE liftW #-}+  -- |+  -- > duplicate = extend id+  -- > fmap (fmap f) . duplicate = duplicate . fmap f+  duplicate :: w a -> w (w a)+  duplicate = extend id --- | Comonadic fixed point-wfix :: Comonad w => w (w a -> a) -> a-wfix w = extract w (extend wfix w)+  -- |+  -- > extend f = fmap f . duplicate+  extend :: (w a -> b) -> w a -> w b+  extend f = fmap f . duplicate --- * Comonads for Prelude types:------ Instances: While Control.Comonad.Instances would be more symmetric--- to the definition of Control.Monad.Instances in base, the reason--- the latter exists is because of Haskell 98 specifying the types--- @'Either' a@, @((,)m)@ and @((->)e)@ and the class Monad without--- having the foresight to require or allow instances between them.--- Here Haskell 98 says nothing about Comonads, so we can include the--- instances directly avoiding the wart of orphan instances.  instance Comonad ((,)e) where+  duplicate p = (fst p, p)   extract = snd -instance (Semigroup m, Monoid m) => Comonad ((->)m) where+instance Monoid m => Comonad ((->)m) where+  duplicate f m = f . mappend m   extract f = f mempty --- * Comonads for types from 'transformers'.------ This isn't really a transformer, so i have no compunction about including the instance here.------ TODO: Petition to move Data.Functor.Identity into base instance Comonad Identity where+  duplicate = Identity   extract = runIdentity --- Provided to avoid an orphan instance. Not proposed to standardize. --- If Comonad moved to base, consider moving instance into transformers? instance Comonad w => Comonad (IdentityT w) where+  extend f (IdentityT m) = IdentityT (extend (f . IdentityT) m)   extract = extract . runIdentityT  instance Comonad Tree where+  duplicate w@(Node _ as) = Node w (map duplicate as)   extract (Node a _) = a +instance Comonad NonEmpty where+  extend f w@ ~(_ :| aas) = f w :| case aas of+      []     -> []+      (a:as) -> toList (extend f (a :| as))+  extract ~(a :| _) = a++-- | A @ComonadApply w@ 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 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 (extract q) = extract (p <@> q)+-- > duplicate (p <*> q) = (\r s -> fmap (r <@> s)) <@> duplicate q <*> duplicate q+--+-- If 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++class Comonad w => ComonadApply w where+  (<@>) :: w (a -> b) -> w a -> w b++  (@>) :: w a -> w b -> w b+  a @> b = const id <$> a <@> b++  (<@) :: w a -> w b -> w a+  a <@ b = const <$> a <@> b++instance Semigroup m => ComonadApply ((,)m) where+  (m, f) <@> (n, a) = (m <> n, f a)+  (m, a) <@  (n, _) = (m <> n, a)+  (m, _)  @> (n, b) = (m <> n, b)++instance ComonadApply NonEmpty where+  (<@>) = ap++instance Monoid m => ComonadApply ((->)m) where+  (<@>) = (<*>)+  (<@ ) = (<* )+  ( @>) = ( *>)++instance ComonadApply Identity where+  (<@>) = (<*>)+  (<@ ) = (<* )+  ( @>) = ( *>)++instance ComonadApply w => ComonadApply (IdentityT w) where+  IdentityT wa <@> IdentityT wb = IdentityT (wa <@> wb)++instance ComonadApply Tree where+  (<@>) = (<*>)+  (<@ ) = (<* )+  ( @>) = ( *>)++-- | A suitable default definition for 'fmap' for a 'Comonad'.+-- Promotes a function to a comonad.+--+-- > fmap f = liftW f = extend (f . extract)+liftW :: Comonad w => (a -> b) -> w a -> w b+liftW f = extend (f . extract)+{-# INLINE liftW #-}++-- | Comonadic fixed point à la Menendez+wfix :: Comonad w => w (w a -> a) -> a+wfix w = extract w (extend wfix w)++-- | Comonadic fixed point à la Orchard+cfix :: Comonad w => (w a -> a) -> w a+cfix f = fix (extend f)+{-# INLINE cfix #-}++-- | 'extend' with the arguments swapped. Dual to '>>=' for a 'Monad'.+(=>>) :: Comonad w => w a -> (w a -> b) -> w b+(=>>) = flip extend+{-# INLINE (=>>) #-}++-- | 'extend' in operator form+(<<=) :: Comonad w => (w a -> b) -> w a -> w b+(<<=) = extend+{-# INLINE (<<=) #-}++-- | Right-to-left Cokleisli composition+(=<=) :: Comonad w => (w b -> c) -> (w a -> b) -> w a -> c+f =<= g = f . extend g+{-# INLINE (=<=) #-}++-- | Left-to-right Cokleisli composition+(=>=) :: Comonad w => (w a -> b) -> (w b -> c) -> w a -> c+f =>= g = g . extend f+{-# INLINE (=>=) #-}++-- | A variant of '<@>' with the arguments reversed.+(<@@>) :: ComonadApply w => w a -> w (a -> b) -> w b+(<@@>) = liftW2 (flip id)+{-# INLINE (<@@>) #-}++-- | Lift a binary function into a comonad with zipping+liftW2 :: ComonadApply 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 :: ComonadApply 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 } +#ifdef __GLASGOW_HASKELL__ instance Typeable1 w => Typeable2 (Cokleisli w) where   typeOf2 twab = mkTyConApp cokleisliTyCon [typeOf1 (wa twab)]         where wa :: Cokleisli w a b -> w a               wa = undefined+#endif  cokleisliTyCon :: TyCon #if MIN_VERSION_base(4,4,0)@@ -124,7 +285,9 @@ instance Comonad w => ArrowChoice (Cokleisli w) where   left = leftApp --- Cokleisli arrows are actually just a special case of a reader monad:+instance ComonadApply w => ArrowLoop (Cokleisli w) where+  loop (Cokleisli f) = Cokleisli (fst . wfix . extend f') where+    f' wa wb = f ((,) <$> wa <@> (snd <$> wb))  instance Functor (Cokleisli w a) where   fmap f (Cokleisli g) = Cokleisli (f . g)@@ -137,50 +300,6 @@   return = Cokleisli . const   Cokleisli k >>= f = Cokleisli $ \w -> runCokleisli (f (k w)) w -instance Comonad NonEmpty where-  extract ~(a :| _) = a---{- $definition--There are two ways to define a comonad:--I. Provide definitions for 'extract' and 'extend'-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 'fmap' = 'liftW'.--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:--> f =>= extract   = f-> extract =>= f   = f-> (f =>= g) =>= h = f =>= (g =>= h)--II. Alternately, you may choose to provide definitions for 'fmap',-'extract', and 'duplicate' satisfying these laws:--> extract . duplicate      = id-> fmap extract . duplicate = id-> duplicate . duplicate    = fmap duplicate . duplicate--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 definition of 'liftW' respectively.---}+-- | Replace the contents of a functor uniformly with a constant value.+($>) :: Functor f => f a -> b -> f b+($>) = flip (<$)
− Data/Functor/Extend.hs
@@ -1,150 +0,0 @@-{-# LANGUAGE CPP #-}--------------------------------------------------------------------------------- |--- Module      :  Data.Functor.Extend--- Copyright   :  (C) 2011 Edward Kmett--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Edward Kmett <ekmett@gmail.com>--- Stability   :  provisional--- Portability :  portable---------------------------------------------------------------------------------module Data.Functor.Extend-  ( -- * $definition-    Extend(..)-  , (=>>)     -- :: Extend w => w a -> (w a -> b) -> w b-  , (<<=)     -- :: Extend w => (w a -> b) -> w a -> w b-  , (=>=)     -- :: Extend w => (w a -> b) -> (w b -> c) -> w a -> c-  , (=<=)     -- :: Extend w => (w b -> c) -> (w a -> b) -> w a -> c-  ) where--import Prelude hiding (id, (.))-import Control.Category-import Control.Monad.Trans.Identity-import Data.Functor.Identity-import Data.Semigroup-import Data.List (tails)-import Data.List.NonEmpty (NonEmpty(..), toList)-import Data.Sequence (Seq) -import qualified Data.Sequence as Seq-import Data.Tree--infixl 1 =>> -infixr 1 <<=, =<=, =>= --class Functor w => Extend w where-  -- | -  -- > duplicate = extend id-  -- > fmap (fmap f) . duplicate = duplicate . fmap f-  duplicate :: w a -> w (w a)-  -- |-  -- > extend f  = fmap f . duplicate-  extend    :: (w a -> b) -> w a -> w b--  extend f = fmap f . duplicate-  duplicate = extend id---- | 'extend' with the arguments swapped. Dual to '>>=' for a 'Monad'.-(=>>) :: Extend w => w a -> (w a -> b) -> w b-(=>>) = flip extend-{-# INLINE (=>>) #-}---- | 'extend' in operator form -(<<=) :: Extend w => (w a -> b) -> w a -> w b-(<<=) = extend-{-# INLINE (<<=) #-}---- | Right-to-left Cokleisli composition -(=<=) :: Extend w => (w b -> c) -> (w a -> b) -> w a -> c-f =<= g = f . extend g-{-# INLINE (=<=) #-}---- | Left-to-right Cokleisli composition-(=>=) :: Extend w => (w a -> b) -> (w b -> c) -> w a -> c-f =>= g = g . extend f -{-# INLINE (=>=) #-}---- * Extends for Prelude types:------ Instances: While Data.Functor.Extend.Instances would be symmetric--- to the definition of Control.Monad.Instances in base, the reason--- the latter exists is because of Haskell 98 specifying the types--- @'Either' a@, @((,)m)@ and @((->)e)@ and the class Monad without--- having the foresight to require or allow instances between them.------ Here Haskell 98 says nothing about Extend, so we can include the--- instances directly avoiding the wart of orphan instances.--instance Extend [] where-  duplicate = tails--instance Extend Maybe where-  duplicate Nothing = Nothing-  duplicate j = Just j--instance Extend (Either a) where-  duplicate (Left a) = Left a-  duplicate r = Right r--instance Extend ((,)e) where-  duplicate p = (fst p, p)--instance Semigroup m => Extend ((->)m) where-  duplicate f m = f . (<>) m--instance Extend Seq where-  duplicate = Seq.tails--instance Extend Tree where-  duplicate w@(Node _ as) = Node w (map duplicate as)---- I can't fix the world--- instance (Monoid m, Extend n) => Extend (ReaderT m n) ---   duplicate f m = f . mappend m---- * Extends for types from 'transformers'.------ This isn't really a transformer, so i have no compunction about including the instance here.------ TODO: Petition to move Data.Functor.Identity into base-instance Extend Identity where-  duplicate = Identity---- Provided to avoid an orphan instance. Not proposed to standardize. --- If Extend moved to base, consider moving instance into transformers?-instance Extend w => Extend (IdentityT w) where-  extend f (IdentityT m) = IdentityT (extend (f . IdentityT) m)--instance Extend NonEmpty where-  extend f w@ ~(_ :| aas) = f w :| case aas of-      []     -> []-      (a:as) -> toList (extend f (a :| as))--{- $definition--There are two ways to define an 'Extend' instance:--I. Provide definitions for 'extend'-satisfying this law:--> extend f . extend g = extend (f . extend g)--II. Alternately, you may choose to provide definitions for 'duplicate' -satisfying this laws:--> duplicate . duplicate    = fmap duplicate . duplicate--These are both equivalent to the statement that (=>=) is associative--> (f =>= g) =>= h = f =>= (g =>= h)--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--These are the default definitions of 'extend' and 'duplicate'.---}
comonad.cabal view
@@ -1,6 +1,6 @@ name:          comonad category:      Control, Comonads-version:       1.1.1.6+version:       3.0 license:       BSD3 cabal-version: >= 1.6 license-file:  LICENSE@@ -27,10 +27,9 @@     base         >= 4       && < 5,     transformers >= 0.2     && < 0.4,     containers   >= 0.3     && < 0.6,-    semigroups   >= 0.8.3.1 && < 0.9+    semigroups   >= 0.8.3   && < 0.8.4    exposed-modules:     Control.Comonad-    Data.Functor.Extend    ghc-options: -Wall