module HaskellWorks.Control.Monad
( whileM,
unlessM,
whileNothingM,
repeatNUntilM_,
repeatNWhileM_,
) where
import HaskellWorks.Prelude
whileM :: Monad m => m Bool -> m ()
whileM :: forall (m :: * -> *). Monad m => m Bool -> m ()
whileM m Bool
act = do
Bool
b <- m Bool
act
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
b (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ m Bool -> m ()
forall (m :: * -> *). Monad m => m Bool -> m ()
whileM m Bool
act
unlessM :: Monad m => m Bool -> m ()
unlessM :: forall (m :: * -> *). Monad m => m Bool -> m ()
unlessM m Bool
act = do
Bool
b <- m Bool
act
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
b (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ m Bool -> m ()
forall (m :: * -> *). Monad m => m Bool -> m ()
unlessM m Bool
act
whileNothingM :: Monad m => m (Maybe a) -> m a
whileNothingM :: forall (m :: * -> *) a. Monad m => m (Maybe a) -> m a
whileNothingM m (Maybe a)
act =
m (Maybe a)
act m (Maybe a) -> (Maybe a -> m a) -> m a
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= m a -> (a -> m a) -> Maybe a -> m a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (m (Maybe a) -> m a
forall (m :: * -> *) a. Monad m => m (Maybe a) -> m a
whileNothingM m (Maybe a)
act) a -> m a
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
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)