{-# LANGUAGE FunctionalDependencies #-}

-- | Module: Control.Monad.Action
--
-- Monoid actions, and the update monad, as well as an @mtl@-style capability
-- type class.
--
-- = A note on functional dependencies
--
-- To ensure easy inference, we make use of functional dependencies (either
-- directly or by an equivalent mechanism on associated type families) on both
-- the 'Action' and 'MonadUpdate' type classes. Specifically, we insist that:
--
-- 1. Any monoidal action determines the state it acts on; and
-- 2. Any particular stack that implements 'MonadUpdate' determines what its
-- action is.
--
-- This means that any given action can act on _exactly_ one state, and that any
-- given stack has at most one state we can act upon. The second restriction
-- above is in line with the other similar @mtl@-style capability type classes
-- (such as @MonadReader@, @MonadState@ etc), while the first is a reasonable
-- choice given that we want to have both good inference and also the ability
-- for different actions to act on the same state. Given that actions are likely
-- to be fairly application-specific, we don't see this as a significant
-- limitation.
module Control.Monad.Action
  ( -- * Monoid actions

    -- ** Class
    Action (..),

    -- ** Wrapper
    Actionable,
    actionable,

    -- * Action monad

    -- ** Transformer
    UpdateT (..),
    runUpdateT,

    -- ** Capability type class
    MonadUpdate (..),
  )
where

import Acc (Acc)
import Control.Monad.Trans (MonadTrans (lift))
import Control.Monad.Trans.Except (ExceptT)
import Control.Monad.Trans.Maybe (MaybeT)
import Control.Monad.Trans.RWS.CPS (RWST)
import Control.Monad.Trans.Reader (ReaderT)
import Control.Monad.Trans.State.Strict (StateT)
import Control.Monad.Trans.Writer.CPS (WriterT)
import Data.Functor (void)
import Data.Kind (Type)
import Data.Monoid (Endo, appEndo)

-- | Describes (left) [monoidal actions on a
-- set](https://en.wikipedia.org/wiki/Semigroup_action). In this case, the type
-- @StateOf a@ is \'the state being acted on\' (or \'the state\'), while @a@ is
-- \'the thing doing the acting\' (or \'the action\').
--
-- = Laws
--
-- Briefly, any instance of @'Action' a@ defines a [monoid
-- homomorphism](https://en.wikipedia.org/wiki/Monoid#Monoid_homomorphisms)
-- between @a@ and @'Endo' (StateOf a)@ (which is essentially @StateOf a ->
-- StateOf a)@. In Haskell terms, this means the following laws must hold:
--
-- 1. @'act' 'mempty'@ @=@ @'mempty'@
-- 2. @'act' x '<>' 'act' y@ @=@ @'act' (x '<>' y)@
--
-- @since 1.0.0
class (Monoid a) => Action (a :: Type) where
  type StateOf a :: Type
  act :: a -> Endo (StateOf a)

-- | Often, we want to take a type that doesn't (naturally) form a 'Monoid' and
-- use it as an action. This can be done using a range of \'free monoid
-- constructions\', including lists. However, these aren't optimal due to the
-- append-heavy (and concatenation-heavy) workloads we typically need from
-- actions.
--
-- 'Actionable' is such a \'free monoid construction\' which \'promotes\' any
-- @a@ into a 'Semigroup' and a 'Monoid'. It is fairly opaque, providing only
-- the instances we really need, but it's designed for efficient appending and
-- concatenation.
--
-- To use 'Actionable', you want to do something like this:
--
-- @
-- data MyState = ...
--
-- data MyType = ...
--
-- newtype MyAction = MyAction (Actionable MyType)
--  deriving (Semigroup, Monoid) via (Actionable MyType)
--
-- instance Action MyAction where
--    type StateOf MyAction = MyState
--    act (MyAction acts) = foldMap go acts
--    where
--      go :: MyType -> Endo MyState
--      go x = Endo $ \oldState -> ...
-- @
--
-- To \'inject\' your type into an 'Actionable', use 'actionable'.
--
-- @since 1.0.0
newtype Actionable a = Actionable (Acc a)
  deriving
    ( -- | @since 1.0.0
      NonEmpty (Actionable a) -> Actionable a
Actionable a -> Actionable a -> Actionable a
(Actionable a -> Actionable a -> Actionable a)
-> (NonEmpty (Actionable a) -> Actionable a)
-> (forall b. Integral b => b -> Actionable a -> Actionable a)
-> Semigroup (Actionable a)
forall b. Integral b => b -> Actionable a -> Actionable a
forall a. NonEmpty (Actionable a) -> Actionable a
forall a. Actionable a -> Actionable a -> Actionable a
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall a b. Integral b => b -> Actionable a -> Actionable a
$c<> :: forall a. Actionable a -> Actionable a -> Actionable a
<> :: Actionable a -> Actionable a -> Actionable a
$csconcat :: forall a. NonEmpty (Actionable a) -> Actionable a
sconcat :: NonEmpty (Actionable a) -> Actionable a
$cstimes :: forall a b. Integral b => b -> Actionable a -> Actionable a
stimes :: forall b. Integral b => b -> Actionable a -> Actionable a
Semigroup,
      -- | @since 1.0.0
      Semigroup (Actionable a)
Actionable a
Semigroup (Actionable a) =>
Actionable a
-> (Actionable a -> Actionable a -> Actionable a)
-> ([Actionable a] -> Actionable a)
-> Monoid (Actionable a)
[Actionable a] -> Actionable a
Actionable a -> Actionable a -> Actionable a
forall a. Semigroup (Actionable a)
forall a. Actionable a
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall a. [Actionable a] -> Actionable a
forall a. Actionable a -> Actionable a -> Actionable a
$cmempty :: forall a. Actionable a
mempty :: Actionable a
$cmappend :: forall a. Actionable a -> Actionable a -> Actionable a
mappend :: Actionable a -> Actionable a -> Actionable a
$cmconcat :: forall a. [Actionable a] -> Actionable a
mconcat :: [Actionable a] -> Actionable a
Monoid
    )
    via Acc a
  deriving
    ( -- | @since 1.0.0
      (forall m. Monoid m => Actionable m -> m)
-> (forall m a. Monoid m => (a -> m) -> Actionable a -> m)
-> (forall m a. Monoid m => (a -> m) -> Actionable a -> m)
-> (forall a b. (a -> b -> b) -> b -> Actionable a -> b)
-> (forall a b. (a -> b -> b) -> b -> Actionable a -> b)
-> (forall b a. (b -> a -> b) -> b -> Actionable a -> b)
-> (forall b a. (b -> a -> b) -> b -> Actionable a -> b)
-> (forall a. (a -> a -> a) -> Actionable a -> a)
-> (forall a. (a -> a -> a) -> Actionable a -> a)
-> (forall a. Actionable a -> [a])
-> (forall a. Actionable a -> Bool)
-> (forall a. Actionable a -> Int)
-> (forall a. Eq a => a -> Actionable a -> Bool)
-> (forall a. Ord a => Actionable a -> a)
-> (forall a. Ord a => Actionable a -> a)
-> (forall a. Num a => Actionable a -> a)
-> (forall a. Num a => Actionable a -> a)
-> Foldable Actionable
forall a. Eq a => a -> Actionable a -> Bool
forall a. Num a => Actionable a -> a
forall a. Ord a => Actionable a -> a
forall m. Monoid m => Actionable m -> m
forall a. Actionable a -> Bool
forall a. Actionable a -> Int
forall a. Actionable a -> [a]
forall a. (a -> a -> a) -> Actionable a -> a
forall m a. Monoid m => (a -> m) -> Actionable a -> m
forall b a. (b -> a -> b) -> b -> Actionable a -> b
forall a b. (a -> b -> b) -> b -> Actionable a -> b
forall (t :: Type -> Type).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall m. Monoid m => Actionable m -> m
fold :: forall m. Monoid m => Actionable m -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Actionable a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> Actionable a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Actionable a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> Actionable a -> m
$cfoldr :: forall a b. (a -> b -> b) -> b -> Actionable a -> b
foldr :: forall a b. (a -> b -> b) -> b -> Actionable a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Actionable a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> Actionable a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Actionable a -> b
foldl :: forall b a. (b -> a -> b) -> b -> Actionable a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Actionable a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> Actionable a -> b
$cfoldr1 :: forall a. (a -> a -> a) -> Actionable a -> a
foldr1 :: forall a. (a -> a -> a) -> Actionable a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Actionable a -> a
foldl1 :: forall a. (a -> a -> a) -> Actionable a -> a
$ctoList :: forall a. Actionable a -> [a]
toList :: forall a. Actionable a -> [a]
$cnull :: forall a. Actionable a -> Bool
null :: forall a. Actionable a -> Bool
$clength :: forall a. Actionable a -> Int
length :: forall a. Actionable a -> Int
$celem :: forall a. Eq a => a -> Actionable a -> Bool
elem :: forall a. Eq a => a -> Actionable a -> Bool
$cmaximum :: forall a. Ord a => Actionable a -> a
maximum :: forall a. Ord a => Actionable a -> a
$cminimum :: forall a. Ord a => Actionable a -> a
minimum :: forall a. Ord a => Actionable a -> a
$csum :: forall a. Num a => Actionable a -> a
sum :: forall a. Num a => Actionable a -> a
$cproduct :: forall a. Num a => Actionable a -> a
product :: forall a. Num a => Actionable a -> a
Foldable
    )
    via Acc

-- | Wrap a value into an 'Actionable'.
--
-- @since 1.0.0
actionable :: a -> Actionable a
actionable :: forall a. a -> Actionable a
actionable = Acc a -> Actionable a
forall a. Acc a -> Actionable a
Actionable (Acc a -> Actionable a) -> (a -> Acc a) -> a -> Actionable a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Acc a
forall a. a -> Acc a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure

-- | A transformer implementing the \'update monad\' pattern, as described
-- [here](https://www.schoolofhaskell.com/user/edwardk/heap-of-successes).
--
-- We leave the state implicit, as it is uniquely determined by the @act@ type,
-- together with the 'Action' type class requirement.
--
-- = Important note
--
-- This implementation is not suitable for any @m@ that throws exceptions. This
-- includes @IO@, @ST@ and anything stacked atop them. For the reasons why, see
-- [here](https://github.com/haskell-effectful/effectful/blob/master/transformers.md#statet).
--
-- @since 1.0.0
newtype UpdateT (act :: Type) (m :: Type -> Type) (a :: Type)
  = UpdateT (StateOf act -> m (act, a))
  deriving stock
    ( -- | @since 1.0.0
      (forall a b. (a -> b) -> UpdateT act m a -> UpdateT act m b)
-> (forall a b. a -> UpdateT act m b -> UpdateT act m a)
-> Functor (UpdateT act m)
forall a b. a -> UpdateT act m b -> UpdateT act m a
forall a b. (a -> b) -> UpdateT act m a -> UpdateT act m b
forall act (m :: Type -> Type) a b.
Functor m =>
a -> UpdateT act m b -> UpdateT act m a
forall act (m :: Type -> Type) a b.
Functor m =>
(a -> b) -> UpdateT act m a -> UpdateT act m b
forall (f :: Type -> Type).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall act (m :: Type -> Type) a b.
Functor m =>
(a -> b) -> UpdateT act m a -> UpdateT act m b
fmap :: forall a b. (a -> b) -> UpdateT act m a -> UpdateT act m b
$c<$ :: forall act (m :: Type -> Type) a b.
Functor m =>
a -> UpdateT act m b -> UpdateT act m a
<$ :: forall a b. a -> UpdateT act m b -> UpdateT act m a
Functor
    )

-- | @since 1.0.0
instance (Action act, Monad m) => Applicative (UpdateT act m) where
  {-# INLINEABLE pure #-}
  pure :: forall a. a -> UpdateT act m a
pure a
x = (StateOf act -> m (act, a)) -> UpdateT act m a
forall act (m :: Type -> Type) a.
(StateOf act -> m (act, a)) -> UpdateT act m a
UpdateT ((StateOf act -> m (act, a)) -> UpdateT act m a)
-> (StateOf act -> m (act, a)) -> UpdateT act m a
forall a b. (a -> b) -> a -> b
$ \StateOf act
_ -> (act, a) -> m (act, a)
forall a. a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (act
forall a. Monoid a => a
mempty, a
x)
  {-# INLINEABLE (<*>) #-}
  UpdateT StateOf act -> m (act, a -> b)
fs <*> :: forall a b.
UpdateT act m (a -> b) -> UpdateT act m a -> UpdateT act m b
<*> UpdateT StateOf act -> m (act, a)
xs = (StateOf act -> m (act, b)) -> UpdateT act m b
forall act (m :: Type -> Type) a.
(StateOf act -> m (act, a)) -> UpdateT act m a
UpdateT ((StateOf act -> m (act, b)) -> UpdateT act m b)
-> (StateOf act -> m (act, b)) -> UpdateT act m b
forall a b. (a -> b) -> a -> b
$ \StateOf act
s -> do
    (act
act1, a -> b
f) <- StateOf act -> m (act, a -> b)
fs StateOf act
s
    let s' :: StateOf act
s' = Endo (StateOf act) -> StateOf act -> StateOf act
forall a. Endo a -> a -> a
appEndo (act -> Endo (StateOf act)
forall a. Action a => a -> Endo (StateOf a)
act act
act1) StateOf act
s
    (act
act2, a
x) <- StateOf act -> m (act, a)
xs StateOf act
s'
    (act, b) -> m (act, b)
forall a. a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (act
act1 act -> act -> act
forall a. Semigroup a => a -> a -> a
<> act
act2, a -> b
f a
x)

-- | @since 1.0.0
instance (Action act, Monad m) => Monad (UpdateT act m) where
  {-# INLINEABLE (>>=) #-}
  UpdateT StateOf act -> m (act, a)
xs >>= :: forall a b.
UpdateT act m a -> (a -> UpdateT act m b) -> UpdateT act m b
>>= a -> UpdateT act m b
f = (StateOf act -> m (act, b)) -> UpdateT act m b
forall act (m :: Type -> Type) a.
(StateOf act -> m (act, a)) -> UpdateT act m a
UpdateT ((StateOf act -> m (act, b)) -> UpdateT act m b)
-> (StateOf act -> m (act, b)) -> UpdateT act m b
forall a b. (a -> b) -> a -> b
$ \StateOf act
s -> do
    (act
act1, a
x) <- StateOf act -> m (act, a)
xs StateOf act
s
    let s' :: StateOf act
s' = Endo (StateOf act) -> StateOf act -> StateOf act
forall a. Endo a -> a -> a
appEndo (act -> Endo (StateOf act)
forall a. Action a => a -> Endo (StateOf a)
act act
act1) StateOf act
s
    let (UpdateT StateOf act -> m (act, b)
applied) = a -> UpdateT act m b
f a
x
    (act
act2, b
y) <- StateOf act -> m (act, b)
applied StateOf act
s'
    (act, b) -> m (act, b)
forall a. a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (act
act1 act -> act -> act
forall a. Semigroup a => a -> a -> a
<> act
act2, b
y)

-- | @since 1.0.0
instance (Action act) => MonadTrans (UpdateT act) where
  {-# INLINEABLE lift #-}
  lift :: forall (m :: Type -> Type) a. Monad m => m a -> UpdateT act m a
lift m a
comp = (StateOf act -> m (act, a)) -> UpdateT act m a
forall act (m :: Type -> Type) a.
(StateOf act -> m (act, a)) -> UpdateT act m a
UpdateT ((StateOf act -> m (act, a)) -> UpdateT act m a)
-> (StateOf act -> m (act, a)) -> UpdateT act m a
forall a b. (a -> b) -> a -> b
$ \StateOf act
_ -> (act
forall a. Monoid a => a
mempty,) (a -> (act, a)) -> m a -> m (act, a)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
comp

-- | As 'runUpdate', except that it produces the results in the \'inner monad\'
-- of 'UpdateT'.
--
-- @since 1.0.0
runUpdateT ::
  forall (act :: Type) (m :: Type -> Type) (a :: Type).
  (Functor m, Action act) =>
  UpdateT act m a ->
  StateOf act ->
  m (StateOf act, act, a)
runUpdateT :: forall act (m :: Type -> Type) a.
(Functor m, Action act) =>
UpdateT act m a -> StateOf act -> m (StateOf act, act, a)
runUpdateT (UpdateT StateOf act -> m (act, a)
comp) StateOf act
s =
  (\(act
act1, a
res) -> (Endo (StateOf act) -> StateOf act -> StateOf act
forall a. Endo a -> a -> a
appEndo (act -> Endo (StateOf act)
forall a. Action a => a -> Endo (StateOf a)
act act
act1) StateOf act
s, act
act1, a
res)) ((act, a) -> (StateOf act, act, a))
-> m (act, a) -> m (StateOf act, act, a)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> StateOf act -> m (act, a)
comp StateOf act
s

-- | An @mtl@-style capability type class describing update monads in general,
-- irrespective of their states and/or actions.
--
-- = Laws
--
-- 1. @'send' x 'Control.Applicative.*>' 'send' y@ @=@ @'send' (x '<>' y)@
--
-- If you define 'update' or 'request', ensure the following also hold:
--
-- 2. @'update' 'mempty'@ @=@ @'pure' ()@
-- 3. @'request' 'Control.Applicative.*>' 'request'@ @=@ @'request'@
-- 4. @'update'@ @=@ @'void' '.' 'send'@
-- 5. @'request'@ @=@ @'send' 'mempty'@
--
-- Laws 4 and 5 form the default definitions of 'update' and 'request'
-- respectively, which obey all these laws.
--
-- @since 1.0.0
class (Action act, Monad m) => MonadUpdate act m | m -> act where
  -- | Performs the given action on the state, returning the result.
  --
  -- @since 1.0.0
  send :: act -> m (StateOf act)

  -- | Performs the given action, returning nothing.
  --
  -- @since 1.0.0
  {-# INLINEABLE update #-}
  update :: act -> m ()
  update = m (StateOf act) -> m ()
forall (f :: Type -> Type) a. Functor f => f a -> f ()
void (m (StateOf act) -> m ())
-> (act -> m (StateOf act)) -> act -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. act -> m (StateOf act)
forall act (m :: Type -> Type).
MonadUpdate act m =>
act -> m (StateOf act)
send

  -- | Retrieves the state without doing anything to it.
  --
  -- @since 1.0.0
  {-# INLINEABLE request #-}
  request :: m (StateOf act)
  request = act -> m (StateOf act)
forall act (m :: Type -> Type).
MonadUpdate act m =>
act -> m (StateOf act)
send (act
forall a. Monoid a => a
mempty :: act)

  {-# MINIMAL send #-}

-- | @since 1.0.0
instance (Action act, Monad m) => MonadUpdate act (UpdateT act m) where
  {-# INLINEABLE send #-}
  send :: act -> UpdateT act m (StateOf act)
send act
x = (StateOf act -> m (act, StateOf act))
-> UpdateT act m (StateOf act)
forall act (m :: Type -> Type) a.
(StateOf act -> m (act, a)) -> UpdateT act m a
UpdateT ((StateOf act -> m (act, StateOf act))
 -> UpdateT act m (StateOf act))
-> (StateOf act -> m (act, StateOf act))
-> UpdateT act m (StateOf act)
forall a b. (a -> b) -> a -> b
$ \StateOf act
s -> (act, StateOf act) -> m (act, StateOf act)
forall a. a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (act
x, Endo (StateOf act) -> StateOf act -> StateOf act
forall a. Endo a -> a -> a
appEndo (act -> Endo (StateOf act)
forall a. Action a => a -> Endo (StateOf a)
act act
x) StateOf act
s)

-- | @since 1.0.0
instance (MonadUpdate act m) => MonadUpdate act (ReaderT r m) where
  {-# INLINEABLE send #-}
  send :: act -> ReaderT r m (StateOf act)
send = m (StateOf act) -> ReaderT r m (StateOf act)
forall (m :: Type -> Type) a. Monad m => m a -> ReaderT r m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (StateOf act) -> ReaderT r m (StateOf act))
-> (act -> m (StateOf act)) -> act -> ReaderT r m (StateOf act)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. act -> m (StateOf act)
forall act (m :: Type -> Type).
MonadUpdate act m =>
act -> m (StateOf act)
send
  {-# INLINEABLE update #-}
  update :: act -> ReaderT r m ()
update = m () -> ReaderT r m ()
forall (m :: Type -> Type) a. Monad m => m a -> ReaderT r m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT r m ()) -> (act -> m ()) -> act -> ReaderT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. act -> m ()
forall act (m :: Type -> Type). MonadUpdate act m => act -> m ()
update
  {-# INLINEABLE request #-}
  request :: ReaderT r m (StateOf act)
request = m (StateOf act) -> ReaderT r m (StateOf act)
forall (m :: Type -> Type) a. Monad m => m a -> ReaderT r m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (StateOf act)
forall act (m :: Type -> Type).
MonadUpdate act m =>
m (StateOf act)
request

-- | @since 1.0.0
instance (MonadUpdate act m) => MonadUpdate act (MaybeT m) where
  {-# INLINEABLE send #-}
  send :: act -> MaybeT m (StateOf act)
send = m (StateOf act) -> MaybeT m (StateOf act)
forall (m :: Type -> Type) a. Monad m => m a -> MaybeT m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (StateOf act) -> MaybeT m (StateOf act))
-> (act -> m (StateOf act)) -> act -> MaybeT m (StateOf act)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. act -> m (StateOf act)
forall act (m :: Type -> Type).
MonadUpdate act m =>
act -> m (StateOf act)
send
  {-# INLINEABLE update #-}
  update :: act -> MaybeT m ()
update = m () -> MaybeT m ()
forall (m :: Type -> Type) a. Monad m => m a -> MaybeT m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> MaybeT m ()) -> (act -> m ()) -> act -> MaybeT m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. act -> m ()
forall act (m :: Type -> Type). MonadUpdate act m => act -> m ()
update
  {-# INLINEABLE request #-}
  request :: MaybeT m (StateOf act)
request = m (StateOf act) -> MaybeT m (StateOf act)
forall (m :: Type -> Type) a. Monad m => m a -> MaybeT m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (StateOf act)
forall act (m :: Type -> Type).
MonadUpdate act m =>
m (StateOf act)
request

-- | @since 1.0.0
instance (MonadUpdate act m) => MonadUpdate act (StateT s m) where
  {-# INLINEABLE send #-}
  send :: act -> StateT s m (StateOf act)
send = m (StateOf act) -> StateT s m (StateOf act)
forall (m :: Type -> Type) a. Monad m => m a -> StateT s m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (StateOf act) -> StateT s m (StateOf act))
-> (act -> m (StateOf act)) -> act -> StateT s m (StateOf act)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. act -> m (StateOf act)
forall act (m :: Type -> Type).
MonadUpdate act m =>
act -> m (StateOf act)
send
  {-# INLINEABLE update #-}
  update :: act -> StateT s m ()
update = m () -> StateT s m ()
forall (m :: Type -> Type) a. Monad m => m a -> StateT s m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> StateT s m ()) -> (act -> m ()) -> act -> StateT s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. act -> m ()
forall act (m :: Type -> Type). MonadUpdate act m => act -> m ()
update
  {-# INLINEABLE request #-}
  request :: StateT s m (StateOf act)
request = m (StateOf act) -> StateT s m (StateOf act)
forall (m :: Type -> Type) a. Monad m => m a -> StateT s m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (StateOf act)
forall act (m :: Type -> Type).
MonadUpdate act m =>
m (StateOf act)
request

-- | @since 1.0.0
instance (MonadUpdate act m) => MonadUpdate act (WriterT w m) where
  {-# INLINEABLE send #-}
  send :: act -> WriterT w m (StateOf act)
send = m (StateOf act) -> WriterT w m (StateOf act)
forall (m :: Type -> Type) a. Monad m => m a -> WriterT w m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (StateOf act) -> WriterT w m (StateOf act))
-> (act -> m (StateOf act)) -> act -> WriterT w m (StateOf act)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. act -> m (StateOf act)
forall act (m :: Type -> Type).
MonadUpdate act m =>
act -> m (StateOf act)
send
  {-# INLINEABLE update #-}
  update :: act -> WriterT w m ()
update = m () -> WriterT w m ()
forall (m :: Type -> Type) a. Monad m => m a -> WriterT w m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> WriterT w m ()) -> (act -> m ()) -> act -> WriterT w m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. act -> m ()
forall act (m :: Type -> Type). MonadUpdate act m => act -> m ()
update
  {-# INLINEABLE request #-}
  request :: WriterT w m (StateOf act)
request = m (StateOf act) -> WriterT w m (StateOf act)
forall (m :: Type -> Type) a. Monad m => m a -> WriterT w m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (StateOf act)
forall act (m :: Type -> Type).
MonadUpdate act m =>
m (StateOf act)
request

-- | @since 1.0.0
instance (MonadUpdate act m) => MonadUpdate act (RWST r w s m) where
  {-# INLINEABLE send #-}
  send :: act -> RWST r w s m (StateOf act)
send = m (StateOf act) -> RWST r w s m (StateOf act)
forall (m :: Type -> Type) a. Monad m => m a -> RWST r w s m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (StateOf act) -> RWST r w s m (StateOf act))
-> (act -> m (StateOf act)) -> act -> RWST r w s m (StateOf act)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. act -> m (StateOf act)
forall act (m :: Type -> Type).
MonadUpdate act m =>
act -> m (StateOf act)
send
  {-# INLINEABLE update #-}
  update :: act -> RWST r w s m ()
update = m () -> RWST r w s m ()
forall (m :: Type -> Type) a. Monad m => m a -> RWST r w s m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> RWST r w s m ())
-> (act -> m ()) -> act -> RWST r w s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. act -> m ()
forall act (m :: Type -> Type). MonadUpdate act m => act -> m ()
update
  {-# INLINEABLE request #-}
  request :: RWST r w s m (StateOf act)
request = m (StateOf act) -> RWST r w s m (StateOf act)
forall (m :: Type -> Type) a. Monad m => m a -> RWST r w s m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (StateOf act)
forall act (m :: Type -> Type).
MonadUpdate act m =>
m (StateOf act)
request

-- | @since 1.0.0
instance (MonadUpdate act m) => MonadUpdate act (ExceptT e m) where
  {-# INLINEABLE send #-}
  send :: act -> ExceptT e m (StateOf act)
send = m (StateOf act) -> ExceptT e m (StateOf act)
forall (m :: Type -> Type) a. Monad m => m a -> ExceptT e m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (StateOf act) -> ExceptT e m (StateOf act))
-> (act -> m (StateOf act)) -> act -> ExceptT e m (StateOf act)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. act -> m (StateOf act)
forall act (m :: Type -> Type).
MonadUpdate act m =>
act -> m (StateOf act)
send
  {-# INLINEABLE update #-}
  update :: act -> ExceptT e m ()
update = m () -> ExceptT e m ()
forall (m :: Type -> Type) a. Monad m => m a -> ExceptT e m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ExceptT e m ()) -> (act -> m ()) -> act -> ExceptT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. act -> m ()
forall act (m :: Type -> Type). MonadUpdate act m => act -> m ()
update
  {-# INLINEABLE request #-}
  request :: ExceptT e m (StateOf act)
request = m (StateOf act) -> ExceptT e m (StateOf act)
forall (m :: Type -> Type) a. Monad m => m a -> ExceptT e m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (StateOf act)
forall act (m :: Type -> Type).
MonadUpdate act m =>
m (StateOf act)
request