module Control.Proxy.Prelude.Kleisli (
foreverK,
replicateK,
liftK,
hoistK,
raise,
raiseK,
hoistPK,
raiseP,
raisePK
) where
import Control.Monad.Morph (MFunctor(hoist))
import Control.Monad.Trans.Class (MonadTrans(lift))
import Control.Proxy.Class (Proxy)
import Control.Proxy.Morph (PFunctor(hoistP))
import Control.Proxy.Trans (ProxyTrans(liftP))
foreverK :: (Monad m) => (a -> m a) -> (a -> m b)
foreverK k = let r = \a -> k a >>= r in r
replicateK :: (Monad m) => Int -> (a -> m a) -> (a -> m a)
replicateK n0 k = go n0 where
go n
| n < 1 = return
| n == 1 = k
| otherwise = \a -> k a >>= go (n 1)
liftK :: (Monad m, MonadTrans t) => (a -> m b) -> (a -> t m b)
liftK k a = lift (k a)
hoistK
:: (Monad m, MFunctor t)
=> (forall a . m a -> n a)
-> (b' -> t m b)
-> (b' -> t n b)
hoistK k p a' = hoist k (p a')
raise :: (Monad m, MFunctor t1, MonadTrans t2) => t1 m r -> t1 (t2 m) r
raise = hoist lift
raiseK
:: (Monad m, MFunctor t1, MonadTrans t2)
=> (q -> t1 m r) -> (q -> t1 (t2 m) r)
raiseK = (hoist lift .)
hoistPK
:: (Monad m, Proxy p1, PFunctor t)
=> (forall r1 . p1 a' a b' b m r1 -> p2 a' a b' b n r1)
-> (q -> t p1 a' a b' b m r2)
-> (q -> t p2 a' a b' b n r2)
hoistPK f = (hoistP f .)
raiseP
:: (Monad m, Proxy p, PFunctor t1, ProxyTrans t2)
=> t1 p a' a b' b m r
-> t1 (t2 p) a' a b' b m r
raiseP = hoistP liftP
raisePK
:: (Monad m, Proxy p, PFunctor t1, ProxyTrans t2)
=> (q -> t1 p a' a b' b m r)
-> (q -> t1 (t2 p) a' a b' b m r)
raisePK = hoistPK liftP