comonad 0.4.0 → 0.5.0
raw patch · 2 files changed
+15/−155 lines, 2 filesdep +functor-apply
Dependencies added: functor-apply
Files
- Control/Comonad.hs +13/−154
- comonad.cabal +2/−1
Control/Comonad.hs view
@@ -12,11 +12,8 @@ -- A 'Comonad' is the categorical dual of a 'Monad'. ---------------------------------------------------------------------------- module Control.Comonad ( - -- * Functors- Functor(..)- , (<$>) -- :: Functor f => (a -> b) -> f a -> f b- , ( $>) -- :: Functor f => f a -> b -> f b -+ -- * FunctorApply+ module Data.Functor.Apply -- * Comonads , Comonad(..) , (=>=) -- :: Comonad w => (w a -> b) -> (w b -> c) -> w a -> c@@ -26,21 +23,13 @@ , liftW -- :: Comonad w => (a -> b) -> w a -> w b , wfix -- :: Comonad w => w (w a -> a) -> a - -- * FunctorApply - strong lax symmetric semimonoidal endofunctors- , FunctorApply(..)- , (<..>) -- :: FunctorApply w => w a -> w (a -> b) -> w b- , liftF2 -- :: FunctorApply w => (a -> b -> c) -> w a -> w b -> w c- , liftF3 -- :: FunctorApply w => (a -> b -> c -> d) -> w a -> w b -> w c -> w d- -- * ComonadApply - strong lax symmetric semimonoidal comonads , ComonadApply , 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 - -- * Wrappers+ -- * Cokleisli Arrows , Cokleisli(..)- , WrappedApplicative(..)- , WrappedApply(..) ) where import Prelude hiding (id, (.))@@ -48,17 +37,13 @@ import Control.Arrow import Control.Category import Control.Monad.Trans.Identity-import Data.Functor+import Data.Functor.Apply import Data.Functor.Identity import Data.Monoid infixl 1 =>> infixr 1 <<=, =<=, =>= -infixl 4 <.>, <., .>, <..>, $> -($>) :: Functor f => f a -> b -> f b-($>) = flip (<$)- {- | There are two ways to define a comonad:@@ -153,7 +138,7 @@ -- * Comonads for Prelude types: -- -- Instances: While Control.Comonad.Instances would be more symmetric--- with the definition of Control.Monad.Instances in base, the reason+-- 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.@@ -171,6 +156,7 @@ -- * 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 extract = runIdentity@@ -183,142 +169,14 @@ extract = extract . runIdentityT extend f (IdentityT m) = IdentityT (extend (f . IdentityT) m) --- | A strong lax symmetric semi-monoidal functor.--class Functor f => FunctorApply f where- (<.>) :: f (a -> b) -> f a -> f b-- -- | a .> b = const id <$> a <.> b- (.>) :: f a -> f b -> f b- a .> b = const id <$> a <.> b-- -- | a <. b = const <$> a <.> b- (<.) :: f a -> f b -> f a- a <. b = const <$> a <.> b---- this only requires a Semigroup-instance Monoid m => FunctorApply ((,)m) where- (<.>) = (<*>)- (<. ) = (<* )- ( .>) = ( *>)---- this only requires a Semigroup-instance Monoid m => FunctorApply ((->)m) where- (<.>) = (<*>)- (<. ) = (<* )- ( .>) = ( *>)--instance FunctorApply ZipList where- (<.>) = (<*>)- (<. ) = (<* )- ( .>) = ( *>)--instance FunctorApply [] where- (<.>) = (<*>)- (<. ) = (<* )- ( .>) = ( *>)--instance FunctorApply IO where- (<.>) = (<*>)- (<. ) = (<* )- ( .>) = ( *>)--instance FunctorApply Maybe where- (<.>) = (<*>)- (<. ) = (<* )- ( .>) = ( *>)--instance FunctorApply Identity where- (<.>) = (<*>)- (<. ) = (<* )- ( .>) = ( *>)--instance FunctorApply w => FunctorApply (IdentityT w) where- IdentityT wa <.> IdentityT wb = IdentityT (wa <.> wb)--instance Monad m => FunctorApply (WrappedMonad m) where- (<.>) = (<*>) - (<. ) = (<* )- ( .>) = ( *>)--instance Monoid m => FunctorApply (Const m) where- (<.>) = (<*>) - (<. ) = (<* )- ( .>) = ( *>)--instance Arrow a => FunctorApply (WrappedArrow a b) where- (<.>) = (<*>) - (<. ) = (<* )- ( .>) = ( *>)---- | Wrap Applicatives to be used as a member of FunctorApply -newtype WrappedApplicative f a = WrappedApplicative { unwrapApplicative :: f a } --instance Functor f => Functor (WrappedApplicative f) where- fmap f (WrappedApplicative a) = WrappedApplicative (f <$> a)--instance Applicative f => FunctorApply (WrappedApplicative f) where- WrappedApplicative f <.> WrappedApplicative a = WrappedApplicative (f <*> a)- WrappedApplicative a <. WrappedApplicative b = WrappedApplicative (a <* b)- WrappedApplicative a .> WrappedApplicative b = WrappedApplicative (a *> b)--instance Applicative f => Applicative (WrappedApplicative f) where- pure = WrappedApplicative . pure- WrappedApplicative f <*> WrappedApplicative a = WrappedApplicative (f <*> a)- WrappedApplicative a <* WrappedApplicative b = WrappedApplicative (a <* b)- WrappedApplicative a *> WrappedApplicative b = WrappedApplicative (a *> b)- --- | Transform a strong lax symmetric semi-monoidal endofunctor into a strong lax symmetric--- monoidal endofunctor by adding a unit.-newtype WrappedApply f a = WrapApply { unwrapApply :: Either (f a) a }--instance Functor f => Functor (WrappedApply f) where- fmap f (WrapApply (Right a)) = WrapApply (Right (f a ))- fmap f (WrapApply (Left fa)) = WrapApply (Left (f <$> fa))--instance FunctorApply f => FunctorApply (WrappedApply f) where- WrapApply (Right f) <.> WrapApply (Right a) = WrapApply (Right (f a ))- WrapApply (Right f) <.> WrapApply (Left fa) = WrapApply (Left (f <$> fa))- WrapApply (Left ff) <.> WrapApply (Right a) = WrapApply (Left (($a) <$> ff))- WrapApply (Left ff) <.> WrapApply (Left fa) = WrapApply (Left (ff <.> fa))-- WrapApply a <. WrapApply (Right _) = WrapApply a- WrapApply (Right a) <. WrapApply (Left fb) = WrapApply (Left (a <$ fb))- WrapApply (Left fa) <. WrapApply (Left fb) = WrapApply (Left (fa <. fb))-- WrapApply (Right _) .> WrapApply b = WrapApply b- WrapApply (Left fa) .> WrapApply (Right b) = WrapApply (Left (fa $> b ))- WrapApply (Left fa) .> WrapApply (Left fb) = WrapApply (Left (fa .> fb))- -instance FunctorApply f => Applicative (WrappedApply f) where- pure a = WrapApply (Right a)- (<*>) = (<.>)- (<* ) = (<. )- ( *>) = ( .>)--instance Comonad f => Comonad (WrappedApply f) where- extract (WrapApply (Right a)) = a- extract (WrapApply (Left fa)) = extract fa- duplicate w@(WrapApply Right{}) = WrapApply (Right w)- duplicate (WrapApply (Left fa)) = WrapApply (Left (extend (WrapApply . Left) fa))+instance Comonad f => Comonad (MaybeApply f) where+ extract (MaybeApply (Right a)) = a+ extract (MaybeApply (Left fa)) = extract fa+ duplicate w@(MaybeApply Right{}) = MaybeApply (Right w)+ duplicate (MaybeApply (Left fa)) = MaybeApply (Left (extend (MaybeApply . Left) fa)) -instance ComonadApply f => ComonadApply (WrappedApply f)+instance ComonadApply f => ComonadApply (MaybeApply f) --- | A variant of '<.>' with the arguments reversed.-(<..>) :: FunctorApply w => w a -> w (a -> b) -> w b-(<..>) = liftF2 (flip id)-{-# INLINE (<..>) #-}---- | Lift a binary function into a comonad with zipping-liftF2 :: FunctorApply w => (a -> b -> c) -> w a -> w b -> w c-liftF2 f a b = f <$> a <.> b-{-# INLINE liftF2 #-}---- | Lift a ternary function into a comonad with zipping-liftF3 :: FunctorApply w => (a -> b -> c -> d) -> w a -> w b -> w c -> w d-liftF3 f a b c = f <$> a <.> b <.> c-{-# INLINE liftF3 #-}- {- | A strong lax symmetric semi-monoidal comonad. As such an instance of @@ -392,3 +250,4 @@ instance Monad (Cokleisli w a) where return = Cokleisli . const Cokleisli k >>= f = Cokleisli $ \w -> runCokleisli (f (k w)) w+
comonad.cabal view
@@ -1,6 +1,6 @@ name: comonad category: Control, Comonads-version: 0.4.0+version: 0.5.0 license: BSD3 cabal-version: >= 1.2 license-file: LICENSE@@ -16,6 +16,7 @@ library build-depends: base >= 4 && < 4.4,+ functor-apply >= 0.5 && < 0.6, transformers >= 0.2.0 && < 0.3 exposed-modules: