{-# LANGUAGE CPP #-}
#if __GLASGOW_HASKELL__ >= 707
{-# LANGUAGE DeriveDataTypeable, StandaloneDeriving, Safe, DefaultSignatures #-}
#elif __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Trustworthy, DefaultSignatures #-}
#endif
#if __GLASGOW_HASKELL__ >= 706
{-# LANGUAGE PolyKinds #-}
#endif
------------------------------------------------------------------------------- |-- Module : Control.Comonad-- Copyright : (C) 2008-2015 Edward Kmett,-- (C) 2004 Dave Menendez-- License : BSD-style (see the file LICENSE)---- Maintainer : Edward Kmett <ekmett@gmail.com>-- Stability : provisional-- Portability : portable------------------------------------------------------------------------------moduleControl.Comonad(-- * ComonadsComonad (..),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,kfix -- :: ComonadApply w => w (w a -> a) -> w 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 _everything_importData.FunctorimportControl.ApplicativeimportControl.ArrowimportControl.CategoryimportControl.Monad(ap)
#if MIN_VERSION_base(4,7,0)
-- Control.Monad.Instances is empty
#else
importControl.Monad.Instances
#endif
importControl.Monad.Trans.IdentityimportData.Functor.IdentityimportqualifiedData.Functor.SumasFSumimportData.List.NonEmptyhiding(map)importData.Semigrouphiding(Product)importData.TaggedimportPreludehiding(id,(.))importControl.Monad.FiximportData.Typeable
#ifdef MIN_VERSION_containers
importData.Tree
#endif
infixl4<@ ,@> ,<@@> ,<@> infixl1=>> infixr1<<= ,=<= ,=>= {- |
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.
-}classFunctorw =>Comonad w where-- |-- @-- 'extract' . 'fmap' f = f . 'extract'-- @::w a ->a -- |-- @-- 'duplicate' = 'extend' 'id'-- 'fmap' ('fmap' f) . 'duplicate' = 'duplicate' . 'fmap' f-- @duplicate ::w a ->w (w a )duplicate =(w a -> w a) -> w a -> w (w a)
forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend w a -> w a
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id-- |-- @-- 'extend' f = 'fmap' f . 'duplicate'-- @extend ::(w a ->b )->w a ->w b extend w a -> b
f =(w a -> b) -> w (w a) -> w b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmapw a -> b
f (w (w a) -> w b) -> (w a -> w (w a)) -> w a -> w b
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 (w :: * -> *) a. Comonad w => w a -> w (w a)
duplicate
#if __GLASGOW_HASKELL__ >= 708
{-# MINIMALextract ,(duplicate |extend )#-}
#endif
instanceComonad ((,)e )whereduplicate :: (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 ){-# INLINEduplicate #-}extract :: (e, a) -> a
extract =(e, a) -> a
forall e a. (e, a) -> a
snd{-# INLINEextract #-}instanceComonad (Arge )whereduplicate :: Arg e a -> Arg e (Arg e a)
duplicate w :: Arg e a
w @(Arge
a a
_)=e -> Arg e a -> Arg e (Arg e a)
forall a b. a -> b -> Arg a b
Arge
a Arg e a
w {-# INLINEduplicate #-}extend :: (Arg e a -> b) -> Arg e a -> Arg e b
extend Arg e a -> b
f w :: Arg e a
w @(Arge
a a
_)=e -> b -> Arg e b
forall a b. a -> b -> Arg a b
Arge
a (Arg e a -> b
f Arg e a
w ){-# INLINEextend #-}extract :: Arg e a -> a
extract (Arge
_a
b )=a
b {-# INLINEextract #-}instanceMonoidm =>Comonad ((->)m )whereduplicate :: (m -> a) -> m -> m -> a
duplicate m -> a
f m
m =m -> a
f (m -> a) -> (m -> m) -> m -> a
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
mappendm
m {-# INLINEduplicate #-}extract :: (m -> a) -> a
extract m -> a
f =m -> a
f m
forall a. Monoid a => a
mempty{-# INLINEextract #-}instanceComonad Identitywhereduplicate :: Identity a -> Identity (Identity a)
duplicate =Identity a -> Identity (Identity a)
forall a. a -> Identity a
Identity{-# INLINEduplicate #-}extract :: Identity a -> a
extract =Identity a -> a
forall a. Identity a -> a
runIdentity{-# INLINEextract #-}
#if __GLASGOW_HASKELL__ >= 706
-- $-- The variable `s` can have any kind.-- For example, here it has kind `Bool`:-- >>> :set -XDataKinds-- >>> extract (Tagged 42 :: Tagged 'True Integer)-- 42
#endif
instanceComonad (Taggeds )whereduplicate :: 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{-# INLINEduplicate #-}extract :: Tagged s a -> a
extract =Tagged s a -> a
forall k (s :: k) a. Tagged s a -> a
unTagged{-# INLINEextract #-}instanceComonad w =>Comonad (IdentityTw )whereextend :: (IdentityT w a -> b) -> IdentityT w a -> IdentityT w b
extend IdentityT w a -> b
f (IdentityTw 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 (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 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 :: IdentityT w a -> a
extract =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 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{-# INLINEextract #-}
#ifdef MIN_VERSION_containers
instanceComonad Treewhereduplicate :: Tree a -> Tree (Tree a)
duplicate w :: Tree a
w @(Nodea
_Forest a
as )=Tree a -> Forest (Tree a) -> Tree (Tree a)
forall a. a -> Forest a -> Tree a
NodeTree a
w ((Tree a -> Tree (Tree a)) -> Forest a -> Forest (Tree a)
forall a b. (a -> b) -> [a] -> [b]
mapTree a -> Tree (Tree a)
forall (w :: * -> *) a. Comonad w => w a -> w (w a)
duplicate Forest a
as )extract :: Tree a -> a
extract (Nodea
a Forest a
_)=a
a {-# INLINEextract #-}
#endif
instanceComonad NonEmptywhereextend :: (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 (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 :: NonEmpty a -> a
extract ~(a
a :|[a]
_)=a
a {-# INLINEextract #-}coproduct ::(f a ->b )->(g a ->b )->FSum.Sumf g a ->b coproduct :: (f a -> b) -> (g a -> b) -> Sum f g a -> b
coproduct f a -> b
f g a -> b
_(FSum.InLf a
x )=f a -> b
f f a
x coproduct f a -> b
_g a -> b
g (FSum.InRg a
y )=g a -> b
g g a
y {-# INLINEcoproduct #-}instance(Comonad f ,Comonad g )=>Comonad (FSum.Sumf g )whereextend :: (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 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 (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 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 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 (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 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 :: 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 (w :: * -> *) a. Comonad w => w a -> a
extract g a -> a
forall (w :: * -> *) a. Comonad w => w a -> a
extract {-# INLINEextract #-}-- | @ComonadApply@ is to @Comonad@ like @Applicative@ is to @Monad@.---- Mathematically, it 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 '<@>' q) = 'extract' p ('extract' q)-- 'duplicate' (p '<@>' q) = ('<@>') '<$>' 'duplicate' p '<@>' '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-- @classComonad w =>ComonadApply w where(<@>) ::w (a ->b )->w a ->w b
#if __GLASGOW_HASKELL__ >= 702
default(<@>) ::Applicativew =>w (a ->b )->w a ->w b (<@>) =w (a -> b) -> w a -> w b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>)
#endif
(@>) ::w a ->w b ->w b w a
a @> w b
b =(b -> b) -> a -> b -> b
forall a b. a -> b -> a
constb -> b
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 (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 (w :: * -> *) a b.
ComonadApply w =>
w (a -> b) -> w a -> w b
<@> w b
b instanceSemigroupm =>ComonadApply ((,)m )where(m
m ,a -> b
f )<@> :: (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 )<@ :: (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
_)@> :: (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 )instanceComonadApply NonEmptywhere<@> :: 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
apinstanceMonoidm =>ComonadApply ((->)m )where<@> :: (m -> a -> b) -> (m -> a) -> m -> b
(<@>) =(m -> a -> b) -> (m -> a) -> m -> b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>)(<@)=(<*)(@>)=(*>)instanceComonadApply Identitywhere<@> :: Identity (a -> b) -> Identity a -> Identity b
(<@>) =Identity (a -> b) -> Identity a -> Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>)(<@)=(<*)(@>)=(*>)instanceComonadApply w =>ComonadApply (IdentityTw )whereIdentityTw (a -> b)
wa <@> :: IdentityT w (a -> b) -> IdentityT w a -> IdentityT w b
<@> IdentityTw 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 (w :: * -> *) a b.
ComonadApply w =>
w (a -> b) -> w a -> w b
<@> w a
wb )
#ifdef MIN_VERSION_containers
instanceComonadApply Treewhere<@> :: Tree (a -> b) -> Tree a -> Tree b
(<@>) =Tree (a -> b) -> Tree a -> Tree b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>)(<@)=(<*)(@>)=(*>)
#endif
-- | A suitable default definition for 'fmap' for a 'Comonad'.-- Promotes a function to a comonad.---- You can only safely use 'liftW' to define 'fmap' if your 'Comonad'-- defines 'extend', not just 'duplicate', since defining-- 'extend' in terms of duplicate uses 'fmap'!---- @-- 'fmap' f = 'liftW' f = 'extend' (f . 'extract')-- @liftW ::Comonad w =>(a ->b )->w a ->w b liftW :: (a -> b) -> w a -> w b
liftW a -> b
f =(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 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 (w :: * -> *) a. Comonad w => w a -> a
extract ){-# INLINEliftW #-}-- | Comonadic fixed point à la David Menendezwfix ::Comonad w =>w (w a ->a )->a wfix :: w (w a -> a) -> a
wfix w (w a -> a)
w =w (w a -> 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 (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 )-- | Comonadic fixed point à la Dominic Orchardcfix ::Comonad w =>(w a ->a )->w a cfix :: (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 (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend w a -> a
f ){-# INLINEcfix #-}-- | Comonadic fixed point à la Kenneth Foner:---- This is the @evaluate@ function from his <https://www.youtube.com/watch?v=F7F-BzOB670 "Getting a Quick Fix on Comonads"> talk.kfix ::ComonadApply w =>w (w a ->a )->w a kfix :: 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 (w :: * -> *) a b.
ComonadApply w =>
w (a -> b) -> w a -> w b
<@> w a -> w (w a)
forall (w :: * -> *) a. Comonad w => w a -> w (w a)
duplicate w a
u {-# INLINEkfix #-}-- | 'extend' with the arguments swapped. Dual to '>>=' for a 'Monad'.(=>>) ::Comonad w =>w a ->(w a ->b )->w b =>> :: 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 (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend {-# INLINE(=>>)#-}-- | 'extend' in operator form(<<=) ::Comonad w =>(w a ->b )->w a ->w b <<= :: (w a -> b) -> w a -> w b
(<<=) =(w a -> b) -> w a -> w b
forall (w :: * -> *) a b. 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 w b -> c
f =<= :: (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 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 (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend w a -> b
g {-# INLINE(=<=)#-}-- | Left-to-right 'Cokleisli' composition(=>=) ::Comonad w =>(w a ->b )->(w b ->c )->w a ->c w a -> b
f =>= :: (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 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 (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend w a -> b
f {-# INLINE(=>=)#-}-- | A variant of '<@>' with the arguments reversed.(<@@>) ::ComonadApply w =>w a ->w (a ->b )->w b <@@> :: 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 k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id){-# INLINE(<@@>)#-}-- | Lift a binary function into a 'Comonad' with zippingliftW2 ::ComonadApply w =>(a ->b ->c )->w a ->w b ->w c liftW2 :: (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 (w :: * -> *) a b.
ComonadApply w =>
w (a -> b) -> w a -> w b
<@> w b
b {-# INLINEliftW2 #-}-- | Lift a ternary function into a 'Comonad' with zippingliftW3 ::ComonadApply w =>(a ->b ->c ->d )->w a ->w b ->w c ->w d liftW3 :: (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 (w :: * -> *) a b.
ComonadApply w =>
w (a -> b) -> w a -> w b
<@> w b
b w (c -> d) -> w c -> w d
forall (w :: * -> *) a b.
ComonadApply w =>
w (a -> b) -> w a -> w b
<@> w c
c {-# INLINEliftW3 #-}-- | The 'Cokleisli' 'Arrow's of a given 'Comonad'newtypeCokleisli w a b =Cokleisli {Cokleisli w a b -> w a -> b
runCokleisli ::w a ->b }
#if __GLASGOW_HASKELL__ >= 707
derivingTypeable
#else
#ifdef __GLASGOW_HASKELL__
instanceTypeable1w=>Typeable2(Cokleisliw)wheretypeOf2twab=mkTyConAppcokleisliTyCon[typeOf1(watwab)]wherewa::Cokleisliwab->wawa=undefined
#endif
cokleisliTyCon::TyCon
#if MIN_VERSION_base(4,4,0)
cokleisliTyCon=mkTyCon3"comonad""Control.Comonad""Cokleisli"
#else
cokleisliTyCon=mkTyCon"Control.Comonad.Cokleisli"
#endif
{-# NOINLINEcokleisliTyCon#-}
#endif
instanceComonad w =>Category(Cokleisli w )whereid :: 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 (w :: * -> *) a. Comonad w => w a -> a
extract Cokleisli w b -> c
f . :: 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 )instanceComonad w =>Arrow(Cokleisli w )wherearr :: (b -> c) -> Cokleisli w b c
arrb -> 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 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 (w :: * -> *) a. Comonad w => w a -> a
extract )first :: Cokleisli w b c -> Cokleisli w (b, d) (c, d)
firstCokleisli w b c
f =Cokleisli w b c
f Cokleisli w b c -> Cokleisli w d d -> Cokleisli w (b, d) (c, d)
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
***Cokleisli w d d
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
idsecond :: Cokleisli w b c -> Cokleisli w (d, b) (d, c)
secondCokleisli w b c
f =Cokleisli w d d
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
idCokleisli w d d -> Cokleisli w b c -> Cokleisli w (d, b) (d, 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 *** :: 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 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 (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 (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 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 (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 &&& :: 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 (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&&w b -> c'
g )instanceComonad w =>ArrowApply(Cokleisli w )whereapp :: 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 (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 )instanceComonad w =>ArrowChoice(Cokleisli w )whereleft :: 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)
leftAppinstanceComonadApply w =>ArrowLoop(Cokleisli w )whereloop :: 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 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 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 (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' )wheref' :: 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 (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 ))instanceFunctor(Cokleisli w a )wherefmap :: (a -> b) -> Cokleisli w a a -> Cokleisli w a b
fmapa -> 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 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 )instanceApplicative(Cokleisli w a )wherepure :: 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 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
constCokleisli w a -> a -> b
f <*> :: 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 ))instanceMonad(Cokleisli w a )wherereturn :: a -> Cokleisli w a a
return=a -> Cokleisli w a a
forall (f :: * -> *) a. Applicative f => a -> f a
pureCokleisli w a -> a
k >>= :: 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
#if !(MIN_VERSION_base(4,7,0))
infixl4$>-- | Replace the contents of a functor uniformly with a constant value.($>)::Functorf=>fa->b->fb($>)=flip(<$)
#endif