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

import Control.Monad {- base -}

-- | 'sequence' of 'repeat'
repeatM :: Monad m => m t -> m [t]
repeatM :: m t -> m [t]
repeatM = [m t] -> m [t]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t 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

-- | 'void' of 'repeatM'.
repeatM_ :: Monad m => m t -> m ()
repeatM_ :: m t -> m ()
repeatM_ = m [t] -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (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.
--
-- > fmap (== 7) (composeM [return . (+ 1),return . (/ 2)] 3)
-- > fmap (== 8) (composeM [return . (* 2),return . (+ 1)] 3)
composeM :: Monad m => [a -> m a] -> a -> m a
composeM :: [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 (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (a -> m a) -> (a -> m a) -> a -> m a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
(<=<) a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return

-- | 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 :: Int -> (b -> m b) -> b -> m b
chainM Int
n b -> m b
f = ((b -> m b) -> (b -> m b) -> b -> m b)
-> (b -> m b) -> [b -> m b] -> b -> m b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (b -> m b) -> (b -> m b) -> b -> m b
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
(<=<) b -> m b
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> (b -> m b) -> [b -> m b]
forall a. Int -> a -> [a]
replicate Int
n b -> m b
f)