{-|
Utilities for 'FRP.Rhine.ClSF.Except' that need not be exported.
-}

module FRP.Rhine.ClSF.Except.Util where

-- transformers
import Control.Monad.Trans.Except
import Control.Monad.Trans.Reader

-- | Commute a 'ReaderT' layer past an 'ExceptT' layer.
commuteExceptReader :: ExceptT e (ReaderT r m) a -> ReaderT r (ExceptT e m) a
commuteExceptReader :: forall e r (m :: Type -> Type) a.
ExceptT e (ReaderT r m) a -> ReaderT r (ExceptT e m) a
commuteExceptReader ExceptT e (ReaderT r m) a
a = forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT forall a b. (a -> b) -> a -> b
$ \r
r -> forall e (m :: Type -> Type) a. m (Either e a) -> ExceptT e m a
ExceptT forall a b. (a -> b) -> a -> b
$ forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (forall e (m :: Type -> Type) a. ExceptT e m a -> m (Either e a)
runExceptT ExceptT e (ReaderT r m) a
a) r
r

-- | Commute the effects of the 'ReaderT' and the 'ExceptT' monad.
commuteReaderExcept :: ReaderT r (ExceptT e m) a -> ExceptT e (ReaderT r m) a
commuteReaderExcept :: forall r e (m :: Type -> Type) a.
ReaderT r (ExceptT e m) a -> ExceptT e (ReaderT r m) a
commuteReaderExcept ReaderT r (ExceptT e m) a
a = forall e (m :: Type -> Type) a. m (Either e a) -> ExceptT e m a
ExceptT forall a b. (a -> b) -> a -> b
$ forall r (m :: Type -> Type) a. (r -> m a) -> ReaderT r m a
ReaderT forall a b. (a -> b) -> a -> b
$ \r
r -> forall e (m :: Type -> Type) a. ExceptT e m a -> m (Either e a)
runExceptT forall a b. (a -> b) -> a -> b
$ forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT ReaderT r (ExceptT e m) a
a r
r