module HaskellWorks.Control.Monad
( repeatNUntilM_,
repeatNWhileM_,
) where
import HaskellWorks.Prelude
repeatNUntilM_ :: ()
=> Monad m
=> Int
-> (Int -> m Bool)
-> m ()
repeatNUntilM_ :: forall (m :: * -> *). Monad m => Int -> (Int -> m Bool) -> m ()
repeatNUntilM_ Int
n Int -> m Bool
action = Int -> m ()
go Int
0
where
go :: Int -> m ()
go Int
i =
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
Bool
shouldTerminate <- Int -> m Bool
action Int
i
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
shouldTerminate (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> m ()
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
repeatNWhileM_ :: ()
=> Monad m
=> Int
-> (Int -> m Bool)
-> m ()
repeatNWhileM_ :: forall (m :: * -> *). Monad m => Int -> (Int -> m Bool) -> m ()
repeatNWhileM_ Int
n Int -> m Bool
action = Int -> m ()
go Int
0
where
go :: Int -> m ()
go Int
i =
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
Bool
shouldContinue <- Int -> m Bool
action Int
i
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
shouldContinue (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> m ()
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)