{-# LANGUAGE CPP #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE PolyKinds #-}
module Control.Comonad (
Comonad(..)
, liftW
, wfix
, cfix
, kfix
, (=>=)
, (=<=)
, (<<=)
, (=>>)
, ComonadApply(..)
, (<@@>)
, liftW2
, liftW3
, Cokleisli(..)
, Functor(..)
, (<$>)
, ($>)
) where
import Data.Functor
import Control.Applicative
import Control.Arrow
import Control.Category
import Control.Monad (ap)
import Control.Monad.Trans.Identity
import Data.Functor.Identity
import qualified Data.Functor.Sum as FSum
import Data.List.NonEmpty hiding (map)
import Data.Semigroup hiding (Product)
import Data.Tagged
import Prelude hiding (id, (.))
import Control.Monad.Fix
#ifdef MIN_VERSION_containers
import Data.Tree
#endif
infixl 4 <@, @>, <@@>, <@>
infixl 1 =>>
infixr 1 <<=, =<=, =>=
class Functor w => Comonad w where
:: w a -> a
duplicate :: w a -> w (w a)
duplicate = (w a -> w a) -> w a -> w (w a)
forall a b. (w a -> b) -> w a -> w b
forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend w a -> w a
forall a. a -> a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
extend :: (w a -> b) -> w a -> w b
extend w a -> b
f = (w a -> b) -> w (w a) -> w b
forall a b. (a -> b) -> w a -> w b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap w a -> b
f (w (w a) -> w b) -> (w a -> w (w a)) -> w a -> w b
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. w a -> w (w a)
forall a. w a -> w (w a)
forall (w :: * -> *) a. Comonad w => w a -> w (w a)
duplicate
{-# MINIMAL extract, (duplicate | extend) #-}
instance Comonad ((,)e) where
duplicate :: forall a. (e, a) -> (e, (e, a))
duplicate (e, a)
p = ((e, a) -> e
forall a b. (a, b) -> a
fst (e, a)
p, (e, a)
p)
{-# INLINE duplicate #-}
extract :: forall a. (e, a) -> a
extract = (e, a) -> a
forall e a. (e, a) -> a
snd
{-# INLINE extract #-}
instance Comonad (Arg e) where
duplicate :: forall a. Arg e a -> Arg e (Arg e a)
duplicate w :: Arg e a
w@(Arg e
a a
_) = e -> Arg e a -> Arg e (Arg e a)
forall a b. a -> b -> Arg a b
Arg e
a Arg e a
w
{-# INLINE duplicate #-}
extend :: forall a b. (Arg e a -> b) -> Arg e a -> Arg e b
extend Arg e a -> b
f w :: Arg e a
w@(Arg e
a a
_) = e -> b -> Arg e b
forall a b. a -> b -> Arg a b
Arg e
a (Arg e a -> b
f Arg e a
w)
{-# INLINE extend #-}
extract :: forall a. Arg e a -> a
extract (Arg e
_ a
b) = a
b
{-# INLINE extract #-}
instance Monoid m => Comonad ((->)m) where
duplicate :: forall a. (m -> a) -> m -> (m -> a)
duplicate m -> a
f m
m = m -> a
f (m -> a) -> (m -> m) -> m -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. m -> m -> m
forall a. Monoid a => a -> a -> a
mappend m
m
{-# INLINE duplicate #-}
extract :: forall a. (m -> a) -> a
extract m -> a
f = m -> a
f m
forall a. Monoid a => a
mempty
{-# INLINE extract #-}
instance Comonad Identity where
duplicate :: forall a. Identity a -> Identity (Identity a)
duplicate = Identity a -> Identity (Identity a)
forall a. a -> Identity a
Identity
{-# INLINE duplicate #-}
extract :: forall a. Identity a -> a
extract = Identity a -> a
forall a. Identity a -> a
runIdentity
{-# INLINE extract #-}
instance Comonad (Tagged s) where
duplicate :: forall a. Tagged s a -> Tagged s (Tagged s a)
duplicate = Tagged s a -> Tagged s (Tagged s a)
forall {k} (s :: k) b. b -> Tagged s b
Tagged
{-# INLINE duplicate #-}
extract :: forall a. Tagged s a -> a
extract = Tagged s a -> a
forall k (s :: k) a. Tagged s a -> a
unTagged
{-# INLINE extract #-}
instance Comonad w => Comonad (IdentityT w) where
extend :: forall a b. (IdentityT w a -> b) -> IdentityT w a -> IdentityT w b
extend IdentityT w a -> b
f (IdentityT w a
m) = w b -> IdentityT w b
forall {k} (f :: k -> *) (a :: k). f a -> IdentityT f a
IdentityT ((w a -> b) -> w a -> w b
forall a b. (w a -> b) -> w a -> w b
forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend (IdentityT w a -> b
f (IdentityT w a -> b) -> (w a -> IdentityT w a) -> w a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. w a -> IdentityT w a
forall {k} (f :: k -> *) (a :: k). f a -> IdentityT f a
IdentityT) w a
m)
extract :: forall a. IdentityT w a -> a
extract = w a -> a
forall a. w a -> a
forall (w :: * -> *) a. Comonad w => w a -> a
extract (w a -> a) -> (IdentityT w a -> w a) -> IdentityT w a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. IdentityT w a -> w a
forall {k} (f :: k -> *) (a :: k). IdentityT f a -> f a
runIdentityT
{-# INLINE extract #-}
#ifdef MIN_VERSION_containers
instance Comonad Tree where
duplicate :: forall a. Tree a -> Tree (Tree a)
duplicate w :: Tree a
w@(Node a
_ [Tree a]
as) = Tree a -> [Tree (Tree a)] -> Tree (Tree a)
forall a. a -> [Tree a] -> Tree a
Node Tree a
w ((Tree a -> Tree (Tree a)) -> [Tree a] -> [Tree (Tree a)]
forall a b. (a -> b) -> [a] -> [b]
map Tree a -> Tree (Tree a)
forall a. Tree a -> Tree (Tree a)
forall (w :: * -> *) a. Comonad w => w a -> w (w a)
duplicate [Tree a]
as)
extract :: forall a. Tree a -> a
extract (Node a
a [Tree a]
_) = a
a
{-# INLINE extract #-}
#endif
instance Comonad NonEmpty where
extend :: forall a b. (NonEmpty a -> b) -> NonEmpty a -> NonEmpty b
extend NonEmpty a -> b
f w :: NonEmpty a
w@(~(a
_ :| [a]
aas)) =
NonEmpty a -> b
f NonEmpty a
w b -> [b] -> NonEmpty b
forall a. a -> [a] -> NonEmpty a
:| case [a]
aas of
[] -> []
(a
a:[a]
as) -> NonEmpty b -> [b]
forall a. NonEmpty a -> [a]
toList ((NonEmpty a -> b) -> NonEmpty a -> NonEmpty b
forall a b. (NonEmpty a -> b) -> NonEmpty a -> NonEmpty b
forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend NonEmpty a -> b
f (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
as))
extract :: forall a. NonEmpty a -> a
extract ~(a
a :| [a]
_) = a
a
{-# INLINE extract #-}
coproduct :: (f a -> b) -> (g a -> b) -> FSum.Sum f g a -> b
coproduct :: forall {k} (f :: k -> *) (a :: k) b (g :: k -> *).
(f a -> b) -> (g a -> b) -> Sum f g a -> b
coproduct f a -> b
f g a -> b
_ (FSum.InL f a
x) = f a -> b
f f a
x
coproduct f a -> b
_ g a -> b
g (FSum.InR g a
y) = g a -> b
g g a
y
{-# INLINE coproduct #-}
instance (Comonad f, Comonad g) => Comonad (FSum.Sum f g) where
extend :: forall a b. (Sum f g a -> b) -> Sum f g a -> Sum f g b
extend Sum f g a -> b
f = (f a -> Sum f g b) -> (g a -> Sum f g b) -> Sum f g a -> Sum f g b
forall {k} (f :: k -> *) (a :: k) b (g :: k -> *).
(f a -> b) -> (g a -> b) -> Sum f g a -> b
coproduct
(f b -> Sum f g b
forall {k} (f :: k -> *) (g :: k -> *) (a :: k). f a -> Sum f g a
FSum.InL (f b -> Sum f g b) -> (f a -> f b) -> f a -> Sum f g b
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (f a -> b) -> f a -> f b
forall a b. (f a -> b) -> f a -> f b
forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend (Sum f g a -> b
f (Sum f g a -> b) -> (f a -> Sum f g a) -> f a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. f a -> Sum f g a
forall {k} (f :: k -> *) (g :: k -> *) (a :: k). f a -> Sum f g a
FSum.InL))
(g b -> Sum f g b
forall {k} (f :: k -> *) (g :: k -> *) (a :: k). g a -> Sum f g a
FSum.InR (g b -> Sum f g b) -> (g a -> g b) -> g a -> Sum f g b
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (g a -> b) -> g a -> g b
forall a b. (g a -> b) -> g a -> g b
forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend (Sum f g a -> b
f (Sum f g a -> b) -> (g a -> Sum f g a) -> g a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. g a -> Sum f g a
forall {k} (f :: k -> *) (g :: k -> *) (a :: k). g a -> Sum f g a
FSum.InR))
extract :: forall a. Sum f g a -> a
extract = (f a -> a) -> (g a -> a) -> Sum f g a -> a
forall {k} (f :: k -> *) (a :: k) b (g :: k -> *).
(f a -> b) -> (g a -> b) -> Sum f g a -> b
coproduct f a -> a
forall a. f a -> a
forall (w :: * -> *) a. Comonad w => w a -> a
extract g a -> a
forall a. g a -> a
forall (w :: * -> *) a. Comonad w => w a -> a
extract
{-# INLINE extract #-}
class Comonad w => ComonadApply w where
(<@>) :: w (a -> b) -> w a -> w b
default (<@>) :: Applicative w => w (a -> b) -> w a -> w b
(<@>) = w (a -> b) -> w a -> w b
forall a b. w (a -> b) -> w a -> w b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>)
(@>) :: w a -> w b -> w b
w a
a @> w b
b = (b -> b) -> a -> b -> b
forall a b. a -> b -> a
const b -> b
forall a. a -> a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id (a -> b -> b) -> w a -> w (b -> b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> w a
a w (b -> b) -> w b -> w b
forall a b. w (a -> b) -> w a -> w b
forall (w :: * -> *) a b.
ComonadApply w =>
w (a -> b) -> w a -> w b
<@> w b
b
(<@) :: w a -> w b -> w a
w a
a <@ w b
b = a -> b -> a
forall a b. a -> b -> a
const (a -> b -> a) -> w a -> w (b -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> w a
a w (b -> a) -> w b -> w a
forall a b. w (a -> b) -> w a -> w b
forall (w :: * -> *) a b.
ComonadApply w =>
w (a -> b) -> w a -> w b
<@> w b
b
instance Semigroup m => ComonadApply ((,)m) where
(m
m, a -> b
f) <@> :: forall a b. (m, a -> b) -> (m, a) -> (m, b)
<@> (m
n, a
a) = (m
m m -> m -> m
forall a. Semigroup a => a -> a -> a
<> m
n, a -> b
f a
a)
(m
m, a
a) <@ :: forall a b. (m, a) -> (m, b) -> (m, a)
<@ (m
n, b
_) = (m
m m -> m -> m
forall a. Semigroup a => a -> a -> a
<> m
n, a
a)
(m
m, a
_) @> :: forall a b. (m, a) -> (m, b) -> (m, b)
@> (m
n, b
b) = (m
m m -> m -> m
forall a. Semigroup a => a -> a -> a
<> m
n, b
b)
instance ComonadApply NonEmpty where
<@> :: forall a b. NonEmpty (a -> b) -> NonEmpty a -> NonEmpty b
(<@>) = NonEmpty (a -> b) -> NonEmpty a -> NonEmpty b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
instance Monoid m => ComonadApply ((->)m) where
<@> :: forall a b. (m -> (a -> b)) -> (m -> a) -> m -> b
(<@>) = (m -> a -> b) -> (m -> a) -> m -> b
forall a b. (m -> (a -> b)) -> (m -> a) -> m -> b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>)
(<@ ) = (<* )
( @>) = ( *>)
instance ComonadApply Identity where
<@> :: forall a b. Identity (a -> b) -> Identity a -> Identity b
(<@>) = Identity (a -> b) -> Identity a -> Identity b
forall a b. Identity (a -> b) -> Identity a -> Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>)
(<@ ) = (<* )
( @>) = ( *>)
instance ComonadApply w => ComonadApply (IdentityT w) where
IdentityT w (a -> b)
wa <@> :: forall a b. IdentityT w (a -> b) -> IdentityT w a -> IdentityT w b
<@> IdentityT w a
wb = w b -> IdentityT w b
forall {k} (f :: k -> *) (a :: k). f a -> IdentityT f a
IdentityT (w (a -> b)
wa w (a -> b) -> w a -> w b
forall a b. w (a -> b) -> w a -> w b
forall (w :: * -> *) a b.
ComonadApply w =>
w (a -> b) -> w a -> w b
<@> w a
wb)
#ifdef MIN_VERSION_containers
instance ComonadApply Tree where
<@> :: forall a b. Tree (a -> b) -> Tree a -> Tree b
(<@>) = Tree (a -> b) -> Tree a -> Tree b
forall a b. Tree (a -> b) -> Tree a -> Tree b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>)
(<@ ) = (<* )
( @>) = ( *>)
#endif
liftW :: Comonad w => (a -> b) -> w a -> w b
liftW :: forall (w :: * -> *) a b. Comonad w => (a -> b) -> w a -> w b
liftW a -> b
f = (w a -> b) -> w a -> w b
forall a b. (w a -> b) -> w a -> w b
forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend (a -> b
f (a -> b) -> (w a -> a) -> w a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. w a -> a
forall a. w a -> a
forall (w :: * -> *) a. Comonad w => w a -> a
extract)
{-# INLINE liftW #-}
wfix :: Comonad w => w (w a -> a) -> a
wfix :: forall (w :: * -> *) a. Comonad w => w (w a -> a) -> a
wfix w (w a -> a)
w = w (w a -> a) -> w a -> a
forall a. w a -> a
forall (w :: * -> *) a. Comonad w => w a -> a
extract w (w a -> a)
w ((w (w a -> a) -> a) -> w (w a -> a) -> w a
forall a b. (w a -> b) -> w a -> w b
forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend w (w a -> a) -> a
forall (w :: * -> *) a. Comonad w => w (w a -> a) -> a
wfix w (w a -> a)
w)
cfix :: Comonad w => (w a -> a) -> w a
cfix :: forall (w :: * -> *) a. Comonad w => (w a -> a) -> w a
cfix w a -> a
f = (w a -> w a) -> w a
forall a. (a -> a) -> a
fix ((w a -> a) -> w a -> w a
forall a b. (w a -> b) -> w a -> w b
forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend w a -> a
f)
{-# INLINE cfix #-}
kfix :: ComonadApply w => w (w a -> a) -> w a
kfix :: forall (w :: * -> *) a. ComonadApply w => w (w a -> a) -> w a
kfix w (w a -> a)
w = (w a -> w a) -> w a
forall a. (a -> a) -> a
fix ((w a -> w a) -> w a) -> (w a -> w a) -> w a
forall a b. (a -> b) -> a -> b
$ \w a
u -> w (w a -> a)
w w (w a -> a) -> w (w a) -> w a
forall a b. w (a -> b) -> w a -> w b
forall (w :: * -> *) a b.
ComonadApply w =>
w (a -> b) -> w a -> w b
<@> w a -> w (w a)
forall a. w a -> w (w a)
forall (w :: * -> *) a. Comonad w => w a -> w (w a)
duplicate w a
u
{-# INLINE kfix #-}
(=>>) :: Comonad w => w a -> (w a -> b) -> w b
=>> :: forall (w :: * -> *) a b. Comonad w => w a -> (w a -> b) -> w b
(=>>) = ((w a -> b) -> w a -> w b) -> w a -> (w a -> b) -> w b
forall a b c. (a -> b -> c) -> b -> a -> c
flip (w a -> b) -> w a -> w b
forall a b. (w a -> b) -> w a -> w b
forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend
{-# INLINE (=>>) #-}
(<<=) :: Comonad w => (w a -> b) -> w a -> w b
<<= :: forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
(<<=) = (w a -> b) -> w a -> w b
forall a b. (w a -> b) -> w a -> w b
forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend
{-# INLINE (<<=) #-}
(=<=) :: Comonad w => (w b -> c) -> (w a -> b) -> w a -> c
w b -> c
f =<= :: forall (w :: * -> *) b c a.
Comonad w =>
(w b -> c) -> (w a -> b) -> w a -> c
=<= w a -> b
g = w b -> c
f (w b -> c) -> (w a -> w b) -> w a -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (w a -> b) -> w a -> w b
forall a b. (w a -> b) -> w a -> w b
forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend w a -> b
g
{-# INLINE (=<=) #-}
(=>=) :: Comonad w => (w a -> b) -> (w b -> c) -> w a -> c
w a -> b
f =>= :: forall (w :: * -> *) a b c.
Comonad w =>
(w a -> b) -> (w b -> c) -> w a -> c
=>= w b -> c
g = w b -> c
g (w b -> c) -> (w a -> w b) -> w a -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (w a -> b) -> w a -> w b
forall a b. (w a -> b) -> w a -> w b
forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend w a -> b
f
{-# INLINE (=>=) #-}
(<@@>) :: ComonadApply w => w a -> w (a -> b) -> w b
<@@> :: forall (w :: * -> *) a b.
ComonadApply w =>
w a -> w (a -> b) -> w b
(<@@>) = (a -> (a -> b) -> b) -> w a -> w (a -> b) -> w b
forall (w :: * -> *) a b c.
ComonadApply w =>
(a -> b -> c) -> w a -> w b -> w c
liftW2 (((a -> b) -> a -> b) -> a -> (a -> b) -> b
forall a b c. (a -> b -> c) -> b -> a -> c
flip (a -> b) -> a -> b
forall a. a -> a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id)
{-# INLINE (<@@>) #-}
liftW2 :: ComonadApply w => (a -> b -> c) -> w a -> w b -> w c
liftW2 :: forall (w :: * -> *) a b c.
ComonadApply w =>
(a -> b -> c) -> w a -> w b -> w c
liftW2 a -> b -> c
f w a
a w b
b = a -> b -> c
f (a -> b -> c) -> w a -> w (b -> c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> w a
a w (b -> c) -> w b -> w c
forall a b. w (a -> b) -> w a -> w b
forall (w :: * -> *) a b.
ComonadApply w =>
w (a -> b) -> w a -> w b
<@> w b
b
{-# INLINE liftW2 #-}
liftW3 :: ComonadApply w => (a -> b -> c -> d) -> w a -> w b -> w c -> w d
liftW3 :: forall (w :: * -> *) a b c d.
ComonadApply w =>
(a -> b -> c -> d) -> w a -> w b -> w c -> w d
liftW3 a -> b -> c -> d
f w a
a w b
b w c
c = a -> b -> c -> d
f (a -> b -> c -> d) -> w a -> w (b -> c -> d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> w a
a w (b -> c -> d) -> w b -> w (c -> d)
forall a b. w (a -> b) -> w a -> w b
forall (w :: * -> *) a b.
ComonadApply w =>
w (a -> b) -> w a -> w b
<@> w b
b w (c -> d) -> w c -> w d
forall a b. w (a -> b) -> w a -> w b
forall (w :: * -> *) a b.
ComonadApply w =>
w (a -> b) -> w a -> w b
<@> w c
c
{-# INLINE liftW3 #-}
newtype Cokleisli w a b = Cokleisli { forall {k} (w :: k -> *) (a :: k) b. Cokleisli w a b -> w a -> b
runCokleisli :: w a -> b }
instance Comonad w => Category (Cokleisli w) where
id :: forall a. Cokleisli w a a
id = (w a -> a) -> Cokleisli w a a
forall {k} (w :: k -> *) (a :: k) b. (w a -> b) -> Cokleisli w a b
Cokleisli w a -> a
forall a. w a -> a
forall (w :: * -> *) a. Comonad w => w a -> a
extract
Cokleisli w b -> c
f . :: forall b c a. Cokleisli w b c -> Cokleisli w a b -> Cokleisli w a c
. Cokleisli w a -> b
g = (w a -> c) -> Cokleisli w a c
forall {k} (w :: k -> *) (a :: k) b. (w a -> b) -> Cokleisli w a b
Cokleisli (w b -> c
f (w b -> c) -> (w a -> b) -> w a -> c
forall (w :: * -> *) b c a.
Comonad w =>
(w b -> c) -> (w a -> b) -> w a -> c
=<= w a -> b
g)
instance Comonad w => Arrow (Cokleisli w) where
arr :: forall b c. (b -> c) -> Cokleisli w b c
arr b -> c
f = (w b -> c) -> Cokleisli w b c
forall {k} (w :: k -> *) (a :: k) b. (w a -> b) -> Cokleisli w a b
Cokleisli (b -> c
f (b -> c) -> (w b -> b) -> w b -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. w b -> b
forall a. w a -> a
forall (w :: * -> *) a. Comonad w => w a -> a
extract)
first :: forall b c d. Cokleisli w b c -> Cokleisli w (b, d) (c, d)
first Cokleisli w b c
f = Cokleisli w b c
f Cokleisli w b c -> Cokleisli w d d -> Cokleisli w (b, d) (c, d)
forall b c b' c'.
Cokleisli w b c -> Cokleisli w b' c' -> Cokleisli w (b, b') (c, c')
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** Cokleisli w d d
forall a. Cokleisli w a a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
second :: forall b c d. Cokleisli w b c -> Cokleisli w (d, b) (d, c)
second Cokleisli w b c
f = Cokleisli w d d
forall a. Cokleisli w a a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id Cokleisli w d d -> Cokleisli w b c -> Cokleisli w (d, b) (d, c)
forall b c b' c'.
Cokleisli w b c -> Cokleisli w b' c' -> Cokleisli w (b, b') (c, c')
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** Cokleisli w b c
f
Cokleisli w b -> c
f *** :: forall b c b' c'.
Cokleisli w b c -> Cokleisli w b' c' -> Cokleisli w (b, b') (c, c')
*** Cokleisli w b' -> c'
g = (w (b, b') -> (c, c')) -> Cokleisli w (b, b') (c, c')
forall {k} (w :: k -> *) (a :: k) b. (w a -> b) -> Cokleisli w a b
Cokleisli (w b -> c
f (w b -> c) -> (w (b, b') -> w b) -> w (b, b') -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ((b, b') -> b) -> w (b, b') -> w b
forall a b. (a -> b) -> w a -> w b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (b, b') -> b
forall a b. (a, b) -> a
fst (w (b, b') -> c) -> (w (b, b') -> c') -> w (b, b') -> (c, c')
forall b c c'. (b -> c) -> (b -> c') -> b -> (c, c')
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& w b' -> c'
g (w b' -> c') -> (w (b, b') -> w b') -> w (b, b') -> c'
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ((b, b') -> b') -> w (b, b') -> w b'
forall a b. (a -> b) -> w a -> w b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (b, b') -> b'
forall e a. (e, a) -> a
snd)
Cokleisli w b -> c
f &&& :: forall b c c'.
Cokleisli w b c -> Cokleisli w b c' -> Cokleisli w b (c, c')
&&& Cokleisli w b -> c'
g = (w b -> (c, c')) -> Cokleisli w b (c, c')
forall {k} (w :: k -> *) (a :: k) b. (w a -> b) -> Cokleisli w a b
Cokleisli (w b -> c
f (w b -> c) -> (w b -> c') -> w b -> (c, c')
forall b c c'. (b -> c) -> (b -> c') -> b -> (c, c')
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& w b -> c'
g)
instance Comonad w => ArrowApply (Cokleisli w) where
app :: forall b c. Cokleisli w (Cokleisli w b c, b) c
app = (w (Cokleisli w b c, b) -> c) -> Cokleisli w (Cokleisli w b c, b) c
forall {k} (w :: k -> *) (a :: k) b. (w a -> b) -> Cokleisli w a b
Cokleisli ((w (Cokleisli w b c, b) -> c)
-> Cokleisli w (Cokleisli w b c, b) c)
-> (w (Cokleisli w b c, b) -> c)
-> Cokleisli w (Cokleisli w b c, b) c
forall a b. (a -> b) -> a -> b
$ \w (Cokleisli w b c, b)
w -> Cokleisli w b c -> w b -> c
forall {k} (w :: k -> *) (a :: k) b. Cokleisli w a b -> w a -> b
runCokleisli ((Cokleisli w b c, b) -> Cokleisli w b c
forall a b. (a, b) -> a
fst (w (Cokleisli w b c, b) -> (Cokleisli w b c, b)
forall a. w a -> a
forall (w :: * -> *) a. Comonad w => w a -> a
extract w (Cokleisli w b c, b)
w)) ((Cokleisli w b c, b) -> b
forall e a. (e, a) -> a
snd ((Cokleisli w b c, b) -> b) -> w (Cokleisli w b c, b) -> w b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> w (Cokleisli w b c, b)
w)
instance Comonad w => ArrowChoice (Cokleisli w) where
left :: forall b c d.
Cokleisli w b c -> Cokleisli w (Either b d) (Either c d)
left = Cokleisli w b c -> Cokleisli w (Either b d) (Either c d)
forall (a :: * -> * -> *) b c d.
ArrowApply a =>
a b c -> a (Either b d) (Either c d)
leftApp
instance ComonadApply w => ArrowLoop (Cokleisli w) where
loop :: forall b d c. Cokleisli w (b, d) (c, d) -> Cokleisli w b c
loop (Cokleisli w (b, d) -> (c, d)
f) = (w b -> c) -> Cokleisli w b c
forall {k} (w :: k -> *) (a :: k) b. (w a -> b) -> Cokleisli w a b
Cokleisli ((c, d) -> c
forall a b. (a, b) -> a
fst ((c, d) -> c) -> (w b -> (c, d)) -> w b -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. w (w (c, d) -> (c, d)) -> (c, d)
forall (w :: * -> *) a. Comonad w => w (w a -> a) -> a
wfix (w (w (c, d) -> (c, d)) -> (c, d))
-> (w b -> w (w (c, d) -> (c, d))) -> w b -> (c, d)
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (w b -> w (c, d) -> (c, d)) -> w b -> w (w (c, d) -> (c, d))
forall a b. (w a -> b) -> w a -> w b
forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend w b -> w (c, d) -> (c, d)
forall {a}. w b -> w (a, d) -> (c, d)
f') where
f' :: w b -> w (a, d) -> (c, d)
f' w b
wa w (a, d)
wb = w (b, d) -> (c, d)
f ((,) (b -> d -> (b, d)) -> w b -> w (d -> (b, d))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> w b
wa w (d -> (b, d)) -> w d -> w (b, d)
forall a b. w (a -> b) -> w a -> w b
forall (w :: * -> *) a b.
ComonadApply w =>
w (a -> b) -> w a -> w b
<@> ((a, d) -> d
forall e a. (e, a) -> a
snd ((a, d) -> d) -> w (a, d) -> w d
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> w (a, d)
wb))
instance Functor (Cokleisli w a) where
fmap :: forall a b. (a -> b) -> Cokleisli w a a -> Cokleisli w a b
fmap a -> b
f (Cokleisli w a -> a
g) = (w a -> b) -> Cokleisli w a b
forall {k} (w :: k -> *) (a :: k) b. (w a -> b) -> Cokleisli w a b
Cokleisli (a -> b
f (a -> b) -> (w a -> a) -> w a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. w a -> a
g)
instance Applicative (Cokleisli w a) where
pure :: forall a. a -> Cokleisli w a a
pure = (w a -> a) -> Cokleisli w a a
forall {k} (w :: k -> *) (a :: k) b. (w a -> b) -> Cokleisli w a b
Cokleisli ((w a -> a) -> Cokleisli w a a)
-> (a -> w a -> a) -> a -> Cokleisli w a a
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a -> w a -> a
forall a b. a -> b -> a
const
Cokleisli w a -> a -> b
f <*> :: forall a b.
Cokleisli w a (a -> b) -> Cokleisli w a a -> Cokleisli w a b
<*> Cokleisli w a -> a
a = (w a -> b) -> Cokleisli w a b
forall {k} (w :: k -> *) (a :: k) b. (w a -> b) -> Cokleisli w a b
Cokleisli (\w a
w -> w a -> a -> b
f w a
w (w a -> a
a w a
w))
instance Monad (Cokleisli w a) where
return :: forall a. a -> Cokleisli w a a
return = a -> Cokleisli w a a
forall a. a -> Cokleisli w a a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
Cokleisli w a -> a
k >>= :: forall a b.
Cokleisli w a a -> (a -> Cokleisli w a b) -> Cokleisli w a b
>>= a -> Cokleisli w a b
f = (w a -> b) -> Cokleisli w a b
forall {k} (w :: k -> *) (a :: k) b. (w a -> b) -> Cokleisli w a b
Cokleisli ((w a -> b) -> Cokleisli w a b) -> (w a -> b) -> Cokleisli w a b
forall a b. (a -> b) -> a -> b
$ \w a
w -> Cokleisli w a b -> w a -> b
forall {k} (w :: k -> *) (a :: k) b. Cokleisli w a b -> w a -> b
runCokleisli (a -> Cokleisli w a b
f (w a -> a
k w a
w)) w a
w