{- | This module combines the wrapping and running functions for the 'Reader',
'Writer' and 'State' monad layers in a single layer.

It is based on the /strict/ 'RWS' monad 'Control.Monad.Trans.RWS.Strict',
so when combining it with other modules such as @mtl@'s, the strict version
has to be included, i.e. 'Control.Monad.RWS.Strict' instead of
'Control.Monad.RWS' or 'Control.Monad.RWS.Lazy'.
-}
module Data.Automaton.Trans.RWS (
  module Data.Automaton.Trans.RWS,
  module Control.Monad.Trans.RWS.Strict,
)
where

-- transformers
import Control.Monad.Trans.RWS.Strict hiding (liftCallCC, liftCatch)

-- automaton
import Data.Automaton (Automaton, withAutomaton)
import Data.Stream.Result (Result (..))

-- * 'RWS' (Reader-Writer-State) monad

-- | Wrap an 'Automaton' with explicit state variables in 'RWST' monad transformer.
rwsS ::
  (Functor m, Monad m, Monoid w) =>
  Automaton m (r, s, a) (w, s, b) ->
  Automaton (RWST r w s m) a b
rwsS :: forall (m :: Type -> Type) w r s a b.
(Functor m, Monad m, Monoid w) =>
Automaton m (r, s, a) (w, s, b) -> Automaton (RWST r w s m) a b
rwsS = (forall s.
 ((r, s, a) -> m (Result s (w, s, b)))
 -> a -> RWST r w s m (Result s b))
-> Automaton m (r, s, a) (w, s, b) -> Automaton (RWST r w s m) a b
forall (m1 :: Type -> Type) (m2 :: Type -> Type) a1 b1 a2 b2.
(Functor m1, Functor m2) =>
(forall s. (a1 -> m1 (Result s b1)) -> a2 -> m2 (Result s b2))
-> Automaton m1 a1 b1 -> Automaton m2 a2 b2
withAutomaton ((forall s.
  ((r, s, a) -> m (Result s (w, s, b)))
  -> a -> RWST r w s m (Result s b))
 -> Automaton m (r, s, a) (w, s, b) -> Automaton (RWST r w s m) a b)
-> (forall s.
    ((r, s, a) -> m (Result s (w, s, b)))
    -> a -> RWST r w s m (Result s b))
-> Automaton m (r, s, a) (w, s, b)
-> Automaton (RWST r w s m) a b
forall a b. (a -> b) -> a -> b
$ \(r, s, a) -> m (Result s (w, s, b))
f a
a -> (r -> s -> m (Result s b, s, w)) -> RWST r w s m (Result s b)
forall r w s (m :: Type -> Type) a.
(r -> s -> m (a, s, w)) -> RWST r w s m a
RWST ((r -> s -> m (Result s b, s, w)) -> RWST r w s m (Result s b))
-> (r -> s -> m (Result s b, s, w)) -> RWST r w s m (Result s b)
forall a b. (a -> b) -> a -> b
$ \r
r s
s ->
  (\(Result s
c (w
w, s
s', b
b)) -> (s -> b -> Result s b
forall s a. s -> a -> Result s a
Result s
c b
b, s
s', w
w))
    (Result s (w, s, b) -> (Result s b, s, w))
-> m (Result s (w, s, b)) -> m (Result s b, s, w)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (r, s, a) -> m (Result s (w, s, b))
f (r
r, s
s, a
a)

-- | Run the 'RWST' layer by making the state variables explicit.
runRWSS ::
  (Functor m, Monad m, Monoid w) =>
  Automaton (RWST r w s m) a b ->
  Automaton m (r, s, a) (w, s, b)
runRWSS :: forall (m :: Type -> Type) w r s a b.
(Functor m, Monad m, Monoid w) =>
Automaton (RWST r w s m) a b -> Automaton m (r, s, a) (w, s, b)
runRWSS = (forall s.
 (a -> RWST r w s m (Result s b))
 -> (r, s, a) -> m (Result s (w, s, b)))
-> Automaton (RWST r w s m) a b -> Automaton m (r, s, a) (w, s, b)
forall (m1 :: Type -> Type) (m2 :: Type -> Type) a1 b1 a2 b2.
(Functor m1, Functor m2) =>
(forall s. (a1 -> m1 (Result s b1)) -> a2 -> m2 (Result s b2))
-> Automaton m1 a1 b1 -> Automaton m2 a2 b2
withAutomaton ((forall s.
  (a -> RWST r w s m (Result s b))
  -> (r, s, a) -> m (Result s (w, s, b)))
 -> Automaton (RWST r w s m) a b -> Automaton m (r, s, a) (w, s, b))
-> (forall s.
    (a -> RWST r w s m (Result s b))
    -> (r, s, a) -> m (Result s (w, s, b)))
-> Automaton (RWST r w s m) a b
-> Automaton m (r, s, a) (w, s, b)
forall a b. (a -> b) -> a -> b
$ \a -> RWST r w s m (Result s b)
f (r
r, s
s, a
a) ->
  (\(Result s
c b
b, s
s', w
w) -> s -> (w, s, b) -> Result s (w, s, b)
forall s a. s -> a -> Result s a
Result s
c (w
w, s
s', b
b))
    ((Result s b, s, w) -> Result s (w, s, b))
-> m (Result s b, s, w) -> m (Result s (w, s, b))
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> RWST r w s m (Result s b) -> r -> s -> m (Result s b, s, w)
forall r w s (m :: Type -> Type) a.
RWST r w s m a -> r -> s -> m (a, s, w)
runRWST (a -> RWST r w s m (Result s b)
f a
a) r
r s
s