{-# LANGUAGE CPP #-}
-- |
-- Copyright  : (c) Ivan Perez and Manuel Baerenz, 2016
-- License    : BSD3
-- Maintainer : ivan.perez@keera.co.uk
--
-- 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 Control.Monad.Trans.MSF.RWS
    ( module Control.Monad.Trans.MSF.RWS
    , module Control.Monad.Trans.RWS.Strict
    )
  where

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

#if !MIN_VERSION_base(4,8,0)
import Data.Functor ((<$>))
import Data.Monoid  (Monoid)
#endif

-- Internal imports
import Data.MonadicStreamFunction (MSF, morphGS)

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

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

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