-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/

-- | Comonads
--   
--   Comonads
@package comonad
@version 4.0

module Data.Functor.Composition

-- | We often need to distinguish between various forms of Functor-like
--   composition in Haskell in order to please the type system. This lets
--   us work with these representations uniformly.
class Composition o
decompose :: Composition o => o f g x -> f (g x)
compose :: Composition o => f (g x) -> o f g x
instance Composition Compose

module Control.Comonad.Trans.Identity

-- | The trivial monad transformer, which maps a monad to an equivalent
--   monad.
newtype IdentityT (m :: * -> *) a :: (* -> *) -> * -> *
IdentityT :: m a -> IdentityT a
runIdentityT :: IdentityT a -> m a

module Control.Comonad

-- | 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 duplicate = extend id extend f = fmap f . duplicate
extract :: Comonad w => w a -> a
duplicate :: Comonad w => w a -> w (w a)
extend :: Comonad w => (w a -> b) -> w a -> w b

-- | 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

-- | Comonadic fixed point à la Menendez
wfix :: Comonad w => w (w a -> a) -> a

-- | Comonadic fixed point à la Orchard
cfix :: Comonad w => (w a -> a) -> w a

-- | Left-to-right Cokleisli composition
(=>=) :: Comonad w => (w a -> b) -> (w b -> c) -> w a -> c

-- | Right-to-left Cokleisli composition
(=<=) :: Comonad w => (w b -> c) -> (w a -> b) -> w a -> c

-- | extend in operator form
(<<=) :: Comonad w => (w a -> b) -> w a -> w b

-- | extend with the arguments swapped. Dual to >>= for
--   a Monad.
(=>>) :: Comonad w => w a -> (w a -> b) -> w b

-- | 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
--   
class Comonad w => ComonadApply w where a @> b = const id <$> a <@> b a <@ b = const <$> a <@> b
(<@>) :: ComonadApply w => w (a -> b) -> w a -> w b
(@>) :: ComonadApply w => w a -> w b -> w b
(<@) :: ComonadApply w => w a -> w b -> w a

-- | A variant of <@> with the arguments reversed.
(<@@>) :: ComonadApply w => w a -> w (a -> b) -> w b

-- | Lift a binary function into a comonad with zipping
liftW2 :: ComonadApply w => (a -> b -> c) -> w a -> w b -> w c

-- | Lift a ternary function into a comonad with zipping
liftW3 :: ComonadApply w => (a -> b -> c -> d) -> w a -> w b -> w c -> w d

-- | The Cokleisli Arrows of a given Comonad
newtype Cokleisli w a b
Cokleisli :: (w a -> b) -> Cokleisli w a b
runCokleisli :: Cokleisli w a b -> w a -> b

-- | The Functor class is used for types that can be mapped over.
--   Instances of Functor should satisfy the following laws:
--   
--   
--   fmap id  ==  id
--   fmap (f . g)  ==  fmap f . fmap g
--   
--   
--   The instances of Functor for lists, Maybe and IO
--   satisfy these laws.
class Functor (f :: * -> *)
fmap :: Functor f => (a -> b) -> f a -> f b
(<$) :: Functor f => a -> f b -> f a

-- | An infix synonym for fmap.
(<$>) :: Functor f => (a -> b) -> f a -> f b

-- | Replace the contents of a functor uniformly with a constant value.
($>) :: Functor f => f a -> b -> f b
instance Monad (Cokleisli w a)
instance Applicative (Cokleisli w a)
instance Functor (Cokleisli w a)
instance ComonadApply w => ArrowLoop (Cokleisli w)
instance Comonad w => ArrowChoice (Cokleisli w)
instance Comonad w => ArrowApply (Cokleisli w)
instance Comonad w => Arrow (Cokleisli w)
instance Comonad w => Category (Cokleisli w)
instance Typeable1 w => Typeable2 (Cokleisli w)
instance ComonadApply Tree
instance ComonadApply w => ComonadApply (IdentityT w)
instance ComonadApply Identity
instance Monoid m => ComonadApply ((->) m)
instance ComonadApply NonEmpty
instance Semigroup m => ComonadApply ((,) m)
instance Comonad NonEmpty
instance Comonad Tree
instance Comonad w => Comonad (IdentityT w)
instance Comonad (Tagged * s)
instance Comonad Identity
instance Monoid m => Comonad ((->) m)
instance Comonad ((,) e)

module Control.Comonad.Trans.Class
class ComonadTrans t
lower :: (ComonadTrans t, Comonad w) => t w a -> w a
instance ComonadTrans IdentityT

module Control.Comonad.Hoist.Class
class ComonadHoist t
cohoist :: (ComonadHoist t, Comonad w, Comonad v) => (forall x. w x -> v x) -> t w a -> t v a
instance ComonadHoist IdentityT

-- | The environment comonad holds a value along with some retrievable
--   context.
--   
--   This module specifies the environment comonad transformer (aka
--   coreader), which is left adjoint to the reader comonad.
--   
--   The following sets up an experiment that retains its initial value in
--   the background:
--   
--   
--   >>> let initial = env 0 0
--   
--   
--   Extract simply retrieves the value:
--   
--   
--   >>> extract initial
--   0
--   
--   
--   Play around with the value, in our case producing a negative value:
--   
--   
--   >>> let experiment = fmap (+ 10) initial
--   
--   >>> extract experiment
--   10
--   
--   
--   Oh noes, something went wrong, 10 isn't very negative! Better restore
--   the initial value using the default:
--   
--   
--   >>> let initialRestored = experiment =>> ask
--   
--   >>> extract initialRestored
--   0
--   
module Control.Comonad.Trans.Env
type Env e = EnvT e Identity

-- | Create an Env using an environment and a value
env :: e -> a -> Env e a
runEnv :: Env e a -> (e, a)
data EnvT e w a
EnvT :: e -> (w a) -> EnvT e w a
runEnvT :: EnvT e w a -> (e, w a)

-- | Gets rid of the environment. This differs from extract in that
--   it will not continue extracting the value from the contained comonad.
lowerEnvT :: EnvT e w a -> w a

-- | Retrieves the environment.
ask :: EnvT e w a -> e

-- | Like ask, but modifies the resulting value with a function.
--   
--   
--   asks = f . ask
--   
asks :: (e -> f) -> EnvT e w a -> f

-- | Modifies the environment using the specified function.
local :: (e -> e') -> EnvT e w a -> EnvT e' w a
instance Traversable w => Traversable (EnvT e w)
instance Foldable w => Foldable (EnvT e w)
instance (Semigroup e, ComonadApply w) => ComonadApply (EnvT e w)
instance ComonadHoist (EnvT e)
instance ComonadTrans (EnvT e)
instance Comonad w => Comonad (EnvT e w)
instance Functor w => Functor (EnvT e w)
instance (Data e, Typeable1 w, Data (w a), Data a) => Data (EnvT e w a)
instance (Typeable s, Typeable1 w, Typeable a) => Typeable (EnvT s w a)
instance (Typeable s, Typeable1 w) => Typeable1 (EnvT s w)

module Control.Comonad.Trans.Store
type Store s = StoreT s Identity

-- | Create a Store using an accessor function and a stored value
store :: (s -> a) -> s -> Store s a
runStore :: Store s a -> (s -> a, s)
data StoreT s w a
StoreT :: (w (s -> a)) -> s -> StoreT s w a
runStoreT :: StoreT s w a -> (w (s -> a), s)

-- | Read the stored value
--   
--   
--   >>> pos $ store fst (1,5)
--   (1,5)
--   
pos :: StoreT s w a -> s

-- | Set the stored value
--   
--   
--   pos . seek (3,7) $ store fst (1,5)
--   (3,7)
--   
--   
--   Seek satisfies the law
--   
--   
--   seek s = peek s . duplicate
--   
seek :: s -> StoreT s w a -> StoreT s w a
seeks :: (s -> s) -> StoreT s w a -> StoreT s w a

-- | Peek at what the current focus would be for a different stored value
--   
--   Peek satisfies the law
--   
--   
--   peek x . extend (peek y) = peek y
--   
peek :: Comonad w => s -> StoreT s w a -> a

-- | Peek at what the current focus would be if the stored value was
--   modified by some function
peeks :: Comonad w => (s -> s) -> StoreT s w a -> a

-- | Applies a functor-valued function to the stored value, and then uses
--   the new accessor to read the resulting focus.
--   
--   
--   >>> let f x = if x > 0 then Just (x^2) else Nothing
--   
--   >>> experiment f $ store (+1) 2
--   Just 5
--   
--   >>> experiment f $ store (+1) (-2)
--   Nothing
--   
experiment :: (Comonad w, Functor f) => (s -> f s) -> StoreT s w a -> f a
instance ComonadHoist (StoreT s)
instance ComonadTrans (StoreT s)
instance Comonad w => Comonad (StoreT s w)
instance (Applicative w, Monoid s) => Applicative (StoreT s w)
instance (ComonadApply w, Semigroup s) => ComonadApply (StoreT s w)
instance Functor w => Functor (StoreT s w)
instance (Typeable s, Typeable1 w, Typeable a) => Typeable (StoreT s w a)
instance (Typeable s, Typeable1 w) => Typeable1 (StoreT s w)

-- | The trace comonad builds up a result by prepending monoidal values to
--   each other.
--   
--   This module specifies the traced comonad transformer (aka the cowriter
--   or exponential comonad transformer).
module Control.Comonad.Trans.Traced
type Traced m = TracedT m Identity
traced :: (m -> a) -> Traced m a
runTraced :: Traced m a -> m -> a
newtype TracedT m w a
TracedT :: w (m -> a) -> TracedT m w a
runTracedT :: TracedT m w a -> w (m -> a)
trace :: Comonad w => m -> TracedT m w a -> a
listen :: Functor w => TracedT m w a -> TracedT m w (a, m)
listens :: Functor w => (m -> b) -> TracedT m w a -> TracedT m w (a, b)
censor :: Functor w => (m -> m) -> TracedT m w a -> TracedT m w a
instance (Typeable s, Typeable1 w) => Typeable1 (TracedT s w)
instance Distributive w => Distributive (TracedT m w)
instance Monoid m => ComonadHoist (TracedT m)
instance Monoid m => ComonadTrans (TracedT m)
instance (Comonad w, Monoid m) => Comonad (TracedT m w)
instance Applicative w => Applicative (TracedT m w)
instance (ComonadApply w, Monoid m) => ComonadApply (TracedT m w)
instance Functor w => Functor (TracedT m w)

module Control.Comonad.Env.Class
class Comonad w => ComonadEnv e w | w -> e
ask :: ComonadEnv e w => w a -> e
asks :: ComonadEnv e w => (e -> e') -> w a -> e'
instance (ComonadEnv e w, Monoid m) => ComonadEnv e (TracedT m w)
instance ComonadEnv e w => ComonadEnv e (IdentityT w)
instance ComonadEnv e w => ComonadEnv e (StoreT t w)
instance ComonadEnv e ((,) e)
instance Comonad w => ComonadEnv e (EnvT e w)

-- | The Env comonad (aka the Coreader, Environment, or Product comonad)
--   
--   A co-Kleisli arrow in the Env comonad is isomorphic to a Kleisli arrow
--   in the reader monad.
--   
--   (a -> e -> m) ~ (a, e) -> m ~ Env e a -> m
module Control.Comonad.Env
class Comonad w => ComonadEnv e w | w -> e
ask :: ComonadEnv e w => w a -> e
asks :: ComonadEnv e w => (e -> e') -> w a -> e'

-- | Modifies the environment using the specified function.
local :: (e -> e') -> EnvT e w a -> EnvT e' w a
type Env e = EnvT e Identity

-- | Create an Env using an environment and a value
env :: e -> a -> Env e a
runEnv :: Env e a -> (e, a)
data EnvT e w a
EnvT :: e -> (w a) -> EnvT e w a
runEnvT :: EnvT e w a -> (e, w a)

module Control.Comonad.Identity

module Control.Comonad.Store.Class
class Comonad w => ComonadStore s w | w -> s where peeks f w = peek (f (pos w)) w seek s = peek s . duplicate seeks f = peeks f . duplicate experiment f w = fmap (`peek` w) (f (pos w))
pos :: ComonadStore s w => w a -> s
peek :: ComonadStore s w => s -> w a -> a
peeks :: ComonadStore s w => (s -> s) -> w a -> a
seek :: ComonadStore s w => s -> w a -> w a
seeks :: ComonadStore s w => (s -> s) -> w a -> w a
experiment :: (ComonadStore s w, Functor f) => (s -> f s) -> w a -> f a
lowerPos :: (ComonadTrans t, ComonadStore s w) => t w a -> s
lowerPeek :: (ComonadTrans t, ComonadStore s w) => s -> t w a -> a
instance (ComonadStore s w, Monoid m) => ComonadStore s (TracedT m w)
instance ComonadStore s w => ComonadStore s (EnvT e w)
instance ComonadStore s w => ComonadStore s (IdentityT w)
instance Comonad w => ComonadStore s (StoreT s w)


module Control.Comonad.Store
class Comonad w => ComonadStore s w | w -> s where peeks f w = peek (f (pos w)) w seek s = peek s . duplicate seeks f = peeks f . duplicate experiment f w = fmap (`peek` w) (f (pos w))
pos :: ComonadStore s w => w a -> s
peek :: ComonadStore s w => s -> w a -> a
peeks :: ComonadStore s w => (s -> s) -> w a -> a
seek :: ComonadStore s w => s -> w a -> w a
seeks :: ComonadStore s w => (s -> s) -> w a -> w a
experiment :: (ComonadStore s w, Functor f) => (s -> f s) -> w a -> f a
type Store s = StoreT s Identity

-- | Create a Store using an accessor function and a stored value
store :: (s -> a) -> s -> Store s a
runStore :: Store s a -> (s -> a, s)
data StoreT s w a
StoreT :: (w (s -> a)) -> s -> StoreT s w a
runStoreT :: StoreT s w a -> (w (s -> a), s)


module Control.Comonad.Traced.Class
class Comonad w => ComonadTraced m w | w -> m
trace :: ComonadTraced m w => m -> w a -> a
traces :: ComonadTraced m w => (a -> m) -> w a -> a
instance ComonadTraced m w => ComonadTraced m (StoreT s w)
instance ComonadTraced m w => ComonadTraced m (EnvT e w)
instance ComonadTraced m w => ComonadTraced m (IdentityT w)
instance (Comonad w, Monoid m) => ComonadTraced m (TracedT m w)


module Control.Comonad.Traced
class Comonad w => ComonadTraced m w | w -> m
trace :: ComonadTraced m w => m -> w a -> a
traces :: ComonadTraced m w => (a -> m) -> w a -> a
type Traced m = TracedT m Identity
traced :: (m -> a) -> Traced m a
runTraced :: Traced m a -> m -> a
newtype TracedT m w a
TracedT :: w (m -> a) -> TracedT m w a
runTracedT :: TracedT m w a -> w (m -> a)


module Data.Functor.Coproduct
newtype Coproduct f g a
Coproduct :: Either (f a) (g a) -> Coproduct f g a
getCoproduct :: Coproduct f g a -> Either (f a) (g a)
left :: f a -> Coproduct f g a
right :: g a -> Coproduct f g a
coproduct :: (f a -> b) -> (g a -> b) -> Coproduct f g a -> b
instance (Eq (f a), Eq (g a)) => Eq (Coproduct f g a)
instance (Ord (f a), Ord (g a)) => Ord (Coproduct f g a)
instance (Read (f a), Read (g a)) => Read (Coproduct f g a)
instance (Show (f a), Show (g a)) => Show (Coproduct f g a)
instance (Contravariant f, Contravariant g) => Contravariant (Coproduct f g)
instance (Comonad f, Comonad g) => Comonad (Coproduct f g)
instance (Traversable f, Traversable g) => Traversable (Coproduct f g)
instance (Foldable f, Foldable g) => Foldable (Coproduct f g)
instance (Functor f, Functor g) => Functor (Coproduct f g)
