{-# LANGUAGE CPP #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE StandaloneDeriving #-}
module Control.Comonad.Trans.Store
(
Store, store, runStore
, StoreT(..), runStoreT
, pos
, seek, seeks
, peek, peeks
, experiment
) where
import Control.Comonad
import Control.Comonad.Hoist.Class
import Control.Comonad.Trans.Class
import Data.Functor.Identity
#if !(MIN_VERSION_base(4,11,0))
import Data.Semigroup
#endif
type Store s = StoreT s Identity
store :: (s -> a) -> s -> Store s a
store :: forall s a. (s -> a) -> s -> Store s a
store s -> a
f s
s = Identity (s -> a) -> s -> StoreT s Identity a
forall s (w :: * -> *) a. w (s -> a) -> s -> StoreT s w a
StoreT ((s -> a) -> Identity (s -> a)
forall a. a -> Identity a
Identity s -> a
f) s
s
runStore :: Store s a -> (s -> a, s)
runStore :: forall s a. Store s a -> (s -> a, s)
runStore (StoreT (Identity s -> a
f) s
s) = (s -> a
f, s
s)
data StoreT s w a = StoreT (w (s -> a)) s
runStoreT :: StoreT s w a -> (w (s -> a), s)
runStoreT :: forall s (w :: * -> *) a. StoreT s w a -> (w (s -> a), s)
runStoreT (StoreT w (s -> a)
wf s
s) = (w (s -> a)
wf, s
s)
instance Functor w => Functor (StoreT s w) where
fmap :: forall a b. (a -> b) -> StoreT s w a -> StoreT s w b
fmap a -> b
f (StoreT w (s -> a)
wf s
s) = w (s -> b) -> s -> StoreT s w b
forall s (w :: * -> *) a. w (s -> a) -> s -> StoreT s w a
StoreT (((s -> a) -> s -> b) -> w (s -> a) -> w (s -> b)
forall a b. (a -> b) -> w a -> w b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> b
f (a -> b) -> (s -> a) -> s -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) w (s -> a)
wf) s
s
instance (ComonadApply w, Semigroup s) => ComonadApply (StoreT s w) where
StoreT w (s -> a -> b)
ff s
m <@> :: forall a b. StoreT s w (a -> b) -> StoreT s w a -> StoreT s w b
<@> StoreT w (s -> a)
fa s
n = w (s -> b) -> s -> StoreT s w b
forall s (w :: * -> *) a. w (s -> a) -> s -> StoreT s w a
StoreT ((s -> a -> b) -> (s -> a) -> s -> b
forall a b. (s -> a -> b) -> (s -> a) -> s -> b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>) ((s -> a -> b) -> (s -> a) -> s -> b)
-> w (s -> a -> b) -> w ((s -> a) -> s -> b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> w (s -> a -> b)
ff w ((s -> a) -> s -> b) -> w (s -> a) -> w (s -> 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 (s -> a)
fa) (s
m s -> s -> s
forall a. Semigroup a => a -> a -> a
<> s
n)
instance (Applicative w, Monoid s) => Applicative (StoreT s w) where
pure :: forall a. a -> StoreT s w a
pure a
a = w (s -> a) -> s -> StoreT s w a
forall s (w :: * -> *) a. w (s -> a) -> s -> StoreT s w a
StoreT ((s -> a) -> w (s -> a)
forall a. a -> w a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> s -> a
forall a b. a -> b -> a
const a
a)) s
forall a. Monoid a => a
mempty
StoreT w (s -> a -> b)
ff s
m <*> :: forall a b. StoreT s w (a -> b) -> StoreT s w a -> StoreT s w b
<*> StoreT w (s -> a)
fa s
n = w (s -> b) -> s -> StoreT s w b
forall s (w :: * -> *) a. w (s -> a) -> s -> StoreT s w a
StoreT ((s -> a -> b) -> (s -> a) -> s -> b
forall a b. (s -> a -> b) -> (s -> a) -> s -> b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>) ((s -> a -> b) -> (s -> a) -> s -> b)
-> w (s -> a -> b) -> w ((s -> a) -> s -> b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> w (s -> a -> b)
ff w ((s -> a) -> s -> b) -> w (s -> a) -> w (s -> 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 (s -> a)
fa) (s -> s -> s
forall a. Monoid a => a -> a -> a
mappend s
m s
n)
instance Comonad w => Comonad (StoreT s w) where
duplicate :: forall a. StoreT s w a -> StoreT s w (StoreT s w a)
duplicate (StoreT w (s -> a)
wf s
s) = w (s -> StoreT s w a) -> s -> StoreT s w (StoreT s w a)
forall s (w :: * -> *) a. w (s -> a) -> s -> StoreT s w a
StoreT ((w (s -> a) -> s -> StoreT s w a)
-> w (s -> a) -> w (s -> StoreT s 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 (s -> a) -> s -> StoreT s w a
forall s (w :: * -> *) a. w (s -> a) -> s -> StoreT s w a
StoreT w (s -> a)
wf) s
s
extend :: forall a b. (StoreT s w a -> b) -> StoreT s w a -> StoreT s w b
extend StoreT s w a -> b
f (StoreT w (s -> a)
wf s
s) = w (s -> b) -> s -> StoreT s w b
forall s (w :: * -> *) a. w (s -> a) -> s -> StoreT s w a
StoreT ((w (s -> a) -> s -> b) -> w (s -> a) -> w (s -> 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 (s -> a)
wf' s
s' -> StoreT s w a -> b
f (w (s -> a) -> s -> StoreT s w a
forall s (w :: * -> *) a. w (s -> a) -> s -> StoreT s w a
StoreT w (s -> a)
wf' s
s')) w (s -> a)
wf) s
s
extract :: forall a. StoreT s w a -> a
extract (StoreT w (s -> a)
wf s
s) = w (s -> a) -> s -> a
forall a. w a -> a
forall (w :: * -> *) a. Comonad w => w a -> a
extract w (s -> a)
wf s
s
instance ComonadTrans (StoreT s) where
lower :: forall (w :: * -> *) a. Comonad w => StoreT s w a -> w a
lower (StoreT w (s -> a)
f s
s) = ((s -> a) -> a) -> w (s -> a) -> w a
forall a b. (a -> b) -> w a -> w b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((s -> a) -> s -> a
forall a b. (a -> b) -> a -> b
$ s
s) w (s -> a)
f
instance ComonadHoist (StoreT s) where
cohoist :: forall (w :: * -> *) (v :: * -> *) a.
(Comonad w, Comonad v) =>
(forall x. w x -> v x) -> StoreT s w a -> StoreT s v a
cohoist forall x. w x -> v x
l (StoreT w (s -> a)
f s
s) = v (s -> a) -> s -> StoreT s v a
forall s (w :: * -> *) a. w (s -> a) -> s -> StoreT s w a
StoreT (w (s -> a) -> v (s -> a)
forall x. w x -> v x
l w (s -> a)
f) s
s
pos :: StoreT s w a -> s
pos :: forall s (w :: * -> *) a. StoreT s w a -> s
pos (StoreT w (s -> a)
_ s
s) = s
s
seek :: s -> StoreT s w a -> StoreT s w a
seek :: forall s (w :: * -> *) a. s -> StoreT s w a -> StoreT s w a
seek s
s ~(StoreT w (s -> a)
f s
_) = w (s -> a) -> s -> StoreT s w a
forall s (w :: * -> *) a. w (s -> a) -> s -> StoreT s w a
StoreT w (s -> a)
f s
s
seeks :: (s -> s) -> StoreT s w a -> StoreT s w a
seeks :: forall s (w :: * -> *) a. (s -> s) -> StoreT s w a -> StoreT s w a
seeks s -> s
f ~(StoreT w (s -> a)
g s
s) = w (s -> a) -> s -> StoreT s w a
forall s (w :: * -> *) a. w (s -> a) -> s -> StoreT s w a
StoreT w (s -> a)
g (s -> s
f s
s)
peek :: Comonad w => s -> StoreT s w a -> a
peek :: forall (w :: * -> *) s a. Comonad w => s -> StoreT s w a -> a
peek s
s (StoreT w (s -> a)
g s
_) = w (s -> a) -> s -> a
forall a. w a -> a
forall (w :: * -> *) a. Comonad w => w a -> a
extract w (s -> a)
g s
s
peeks :: Comonad w => (s -> s) -> StoreT s w a -> a
peeks :: forall (w :: * -> *) s a.
Comonad w =>
(s -> s) -> StoreT s w a -> a
peeks s -> s
f ~(StoreT w (s -> a)
g s
s) = w (s -> a) -> s -> a
forall a. w a -> a
forall (w :: * -> *) a. Comonad w => w a -> a
extract w (s -> a)
g (s -> s
f s
s)
experiment :: (Comonad w, Functor f) => (s -> f s) -> StoreT s w a -> f a
experiment :: forall (w :: * -> *) (f :: * -> *) s a.
(Comonad w, Functor f) =>
(s -> f s) -> StoreT s w a -> f a
experiment s -> f s
f (StoreT w (s -> a)
wf s
s) = w (s -> a) -> s -> a
forall a. w a -> a
forall (w :: * -> *) a. Comonad w => w a -> a
extract w (s -> a)
wf (s -> a) -> f s -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> f s
f s
s