module Pipes.Lift (
distribute
, errorP
, runErrorP
, catchError
, liftCatchError
, maybeP
, runMaybeP
, readerP
, runReaderP
, stateP
, runStateP
, evalStateP
, execStateP
, writerP
, runWriterP
, execWriterP
, rwsP
, runRWSP
, evalRWSP
, execRWSP
) where
import Control.Monad.Trans.Class (lift, MonadTrans(..))
import qualified Control.Monad.Trans.Error as E
import qualified Control.Monad.Trans.Maybe as M
import qualified Control.Monad.Trans.Reader as R
import qualified Control.Monad.Trans.State.Strict as S
import qualified Control.Monad.Trans.Writer.Strict as W
import qualified Control.Monad.Trans.RWS.Strict as RWS
import Data.Monoid (Monoid)
import Pipes.Internal (Proxy(..), unsafeHoist)
import Control.Monad.Morph (hoist, MFunctor(..))
import Pipes.Core (runEffect, request, respond, (//>), (>\\))
distribute
:: ( Monad m
, MonadTrans t
, MFunctor t
, Monad (t m)
, Monad (t (Proxy a' a b' b m))
)
=> Proxy a' a b' b (t m) r
-> t (Proxy a' a b' b m) r
distribute p = runEffect $ request' >\\ unsafeHoist (hoist lift) p //> respond'
where
request' = lift . lift . request
respond' = lift . lift . respond
errorP
:: (Monad m, E.Error e)
=> Proxy a' a b' b m (Either e r)
-> Proxy a' a b' b (E.ErrorT e m) r
errorP p = do
x <- unsafeHoist lift p
lift $ E.ErrorT (return x)
runErrorP
:: (Monad m, E.Error e)
=> Proxy a' a b' b (E.ErrorT e m) r
-> Proxy a' a b' b m (Either e r)
runErrorP = E.runErrorT . distribute
catchError
:: (Monad m, E.Error e)
=> Proxy a' a b' b (E.ErrorT e m) r
-> (e -> Proxy a' a b' b (E.ErrorT e m) r)
-> Proxy a' a b' b (E.ErrorT e m) r
catchError e h = errorP . E.runErrorT $
E.catchError (distribute e) (distribute . h)
liftCatchError
:: Monad m
=> ( m (Proxy a' a b' b m r)
-> (e -> m (Proxy a' a b' b m r))
-> m (Proxy a' a b' b m r) )
-> (Proxy a' a b' b m r
-> (e -> Proxy a' a b' b m r)
-> Proxy a' a b' b m r)
liftCatchError c p0 f = go p0
where
go p = case p of
Request a' fa -> Request a' (\a -> go (fa a ))
Respond b fb' -> Respond b (\b' -> go (fb' b'))
Pure r -> Pure r
M m -> M ((do
p' <- m
return (go p') ) `c` (\e -> return (f e)) )
maybeP
:: Monad m
=> Proxy a' a b' b m (Maybe r) -> Proxy a' a b' b (M.MaybeT m) r
maybeP p = do
x <- unsafeHoist lift p
lift $ M.MaybeT (return x)
runMaybeP
:: Monad m
=> Proxy a' a b' b (M.MaybeT m) r
-> Proxy a' a b' b m (Maybe r)
runMaybeP p = M.runMaybeT $ distribute p
readerP
:: Monad m
=> (i -> Proxy a' a b' b m r) -> Proxy a' a b' b (R.ReaderT i m) r
readerP k = do
i <- lift R.ask
unsafeHoist lift (k i)
runReaderP
:: Monad m
=> i
-> Proxy a' a b' b (R.ReaderT i m) r
-> Proxy a' a b' b m r
runReaderP r p = (`R.runReaderT` r) $ distribute p
stateP
:: Monad m
=> (s -> Proxy a' a b' b m (r, s)) -> Proxy a' a b' b (S.StateT s m) r
stateP k = do
s <- lift S.get
(r, s') <- unsafeHoist lift (k s)
lift (S.put s')
return r
runStateP
:: Monad m
=> s
-> Proxy a' a b' b (S.StateT s m) r
-> Proxy a' a b' b m (r, s)
runStateP s p = (`S.runStateT` s) $ distribute p
evalStateP
:: Monad m
=> s
-> Proxy a' a b' b (S.StateT s m) r
-> Proxy a' a b' b m r
evalStateP s p = fmap fst $ runStateP s p
execStateP
:: Monad m
=> s
-> Proxy a' a b' b (S.StateT s m) r
-> Proxy a' a b' b m s
execStateP s p = fmap snd $ runStateP s p
writerP
:: (Monad m, Monoid w)
=> Proxy a' a b' b m (r, w) -> Proxy a' a b' b (W.WriterT w m) r
writerP p = do
(r, w) <- unsafeHoist lift p
lift $ W.tell w
return r
runWriterP
:: (Monad m, Monoid w)
=> Proxy a' a b' b (W.WriterT w m) r
-> Proxy a' a b' b m (r, w)
runWriterP p = W.runWriterT $ distribute p
execWriterP
:: (Monad m, Monoid w)
=> Proxy a' a b' b (W.WriterT w m) r
-> Proxy a' a b' b m w
execWriterP p = fmap snd $ runWriterP p
rwsP
:: (Monad m, Monoid w)
=> (i -> s -> Proxy a' a b' b m (r, s, w))
-> Proxy a' a b' b (RWS.RWST i w s m) r
rwsP k = do
i <- lift RWS.ask
s <- lift RWS.get
(r, s', w) <- unsafeHoist lift (k i s)
lift $ do
RWS.put s'
RWS.tell w
return r
runRWSP
:: (Monad m, Monoid w)
=> r
-> s
-> Proxy a' a b' b (RWS.RWST r w s m) d
-> Proxy a' a b' b m (d, s, w)
runRWSP i s p = (\b -> RWS.runRWST b i s) $ distribute p
evalRWSP
:: (Monad m, Monoid w)
=> r
-> s
-> Proxy a' a b' b (RWS.RWST r w s m) d
-> Proxy a' a b' b m (d, w)
evalRWSP i s p = fmap f $ runRWSP i s p
where
f x = let (r, _, w) = x in (r, w)
execRWSP
:: (Monad m, Monoid w)
=> r
-> s
-> Proxy a' a b' b (RWS.RWST r w s m) d
-> Proxy a' a b' b m (s, w)
execRWSP i s p = fmap f $ runRWSP i s p
where
f x = let (_, s', w) = x in (s', w)