module Control.Monad.HT where
import qualified Control.Monad as M
import qualified Data.List as List
import Prelude hiding (repeat, until, )
infixr 1 <=<
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> (a -> m c)
(<=<) f g = (f =<<) . g
repeat :: (Monad m) => m a -> m [a]
repeat x =
let go = lift2 (:) x go in go
nest :: (Monad m) => Int -> (a -> m a) -> a -> m a
nest n f x0 = M.foldM (\x () -> f x) x0 (List.replicate n ())
until, untilM :: (Monad m) => (a -> Bool) -> m a -> m a
untilM = until
until p m =
let go =
do x <- m
if p x
then return x
else go
in go
iterateLimit, iterateLimitM :: Monad m => Int -> (a -> m a) -> a -> m [a]
iterateLimitM = iterateLimit
iterateLimit m f =
let aux n x =
lift (x:) $
if n==0
then return []
else aux (n1) =<< f x
in aux m
iterate :: Monad m => (a -> m a) -> a -> m [a]
iterate f =
let go x = lift (x:) $ go =<< f x
in go
andLazy :: (Monad m) => m Bool -> m Bool -> m Bool
andLazy m0 m1 =
m0 >>= \b ->
if b
then m1
else return False
orLazy :: (Monad m) => m Bool -> m Bool -> m Bool
orLazy m0 m1 =
m0 >>= \b ->
if b
then return True
else m1
void :: (Monad m) => m a -> m ()
void = lift (const ())
for :: Monad m => [a] -> (a -> m b) -> m [b]
for = M.forM
map :: Monad m => (a -> m b) -> [a] -> m [b]
map = M.mapM
zipWith :: Monad m => (a -> b -> m c) -> [a] -> [b] -> m [c]
zipWith = M.zipWithM
chain :: (Monad m) => [a -> m a] -> (a -> m a)
chain = foldr (flip (<=<)) return
filter :: Monad m => (a -> m Bool) -> [a] -> m [a]
filter = M.filterM
replicate :: Monad m => Int -> m a -> m [a]
replicate = M.replicateM
lift :: Monad m => (a -> r) -> m a -> m r
lift = M.liftM
lift2 ::
Monad m => (a -> b -> r) -> m a -> m b -> m r
lift2 = M.liftM2
lift3 ::
Monad m => (a -> b -> c -> r) -> m a -> m b -> m c -> m r
lift3 = M.liftM3
lift4 ::
Monad m =>
(a -> b -> c -> d -> r) -> m a -> m b -> m c -> m d -> m r
lift4 = M.liftM4
lift5 ::
Monad m =>
(a -> b -> c -> d -> e -> r) ->
m a -> m b -> m c -> m d -> m e -> m r
lift5 = M.liftM5
liftJoin2 :: (Monad m) => (a -> b -> m c) -> m a -> m b -> m c
liftJoin2 f ma mb =
M.join (lift2 f ma mb)
liftJoin3 :: (Monad m) => (a -> b -> c -> m d) -> m a -> m b -> m c -> m d
liftJoin3 f ma mb mc =
M.join (lift3 f ma mb mc)
liftJoin4 ::
(Monad m) =>
(a -> b -> c -> d -> m e) ->
m a -> m b -> m c -> m d -> m e
liftJoin4 f ma mb mc md =
M.join (lift4 f ma mb mc md)
liftJoin5 ::
(Monad m) =>
(a -> b -> c -> d -> e -> m f) ->
m a -> m b -> m c -> m d -> m e -> m f
liftJoin5 f ma mb mc md me =
M.join (lift5 f ma mb mc md me)