-- | Common 'Control.Monad' variations.
module Sound.Sc3.Common.Monad where

-- | 'sequence' of 'repeat'
repeatM :: Monad m => m t -> m [t]
repeatM :: forall (m :: * -> *) t. Monad m => m t -> m [t]
repeatM = [m t] -> m [t]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence ([m t] -> m [t]) -> (m t -> [m t]) -> m t -> m [t]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m t -> [m t]
forall a. a -> [a]
repeat

-- | This is the same function as Control.Monad.void, which however hugs does not know of.
mvoid :: Monad m => m a -> m ()
mvoid :: forall (m :: * -> *) a. Monad m => m a -> m ()
mvoid m a
f = m a
f m a -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()

-- | 'void' of 'repeatM'.
repeatM_ :: Monad m => m t -> m ()
repeatM_ :: forall (m :: * -> *) a. Monad m => m a -> m ()
repeatM_ = m [t] -> m ()
forall (m :: * -> *) a. Monad m => m a -> m ()
mvoid (m [t] -> m ()) -> (m t -> m [t]) -> m t -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m t -> m [t]
forall (m :: * -> *) t. Monad m => m t -> m [t]
repeatM

{- | Right to left compositon of 'Monad' functions.

>>> composeM [return . (+ 1),return . (* 2)] 3
7

>>> composeM [return . (* 2),return . (+ 1)] 3
8
-}
composeM :: Monad m => [a -> m a] -> a -> m a
composeM :: forall (m :: * -> *) a. Monad m => [a -> m a] -> a -> m a
composeM = ((a -> m a) -> (a -> m a) -> a -> m a)
-> (a -> m a) -> [a -> m a] -> a -> m a
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\a -> m a
f a -> m a
g -> \a
x -> a -> m a
g a
x m a -> (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
>>= a -> m a
f) a -> m a
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return -- foldr (<=<) return except hugs doesn't know of <=<

{- | Feed forward composition of /n/ applications of /f/.

> fmap (== 3) (chainM 3 (return . (+ 1)) 0)
-}
chainM :: Monad m => Int -> (b -> m b) -> b -> m b
chainM :: forall (m :: * -> *) b. Monad m => Int -> (b -> m b) -> b -> m b
chainM Int
n b -> m b
f = [b -> m b] -> b -> m b
forall (m :: * -> *) a. Monad m => [a -> m a] -> a -> m a
composeM (Int -> (b -> m b) -> [b -> m b]
forall a. Int -> a -> [a]
replicate Int
n b -> m b
f)