{-# LANGUAGE ExistentialQuantification #-} module Control.Monad.Extras ( ifM, unlessM, whenM, intercalateM )where import Control.Monad -- | A version of if with monadic test. ifM :: Monad m => m Bool -> m a -> m a -> m a ifM i t e = do i' <- i if i' then t else e -- | A version of unless with monadic test unlessM :: Monad m => m Bool -> m () -> m () unlessM p me = do p' <- p unless p' me -- | A version of when with monadic test whenM :: Monad m => m Bool -> m () -> m () whenM p me = do p' <- p when p' me {- | Folds the second list with the function applied to the first, intercalating the evaluation. That is: intercalateM f -> [a00, a10, a20] -> [b1, b2] = do a01 <- f a00 b1 a11 <- f a10 b1 a21 <- f a20 b1 a02 <- f a11 b2 a12 <- f a21 b2 a22 <- f a31 b2 return [a02, a12, a22] Usefull for consuming lazy sequences. -} intercalateM :: Monad m => (a -> b -> m a) -> [a] -> [b] -> m [a] intercalateM _ aa [] = return aa intercalateM f aa (b:bb) = do aa' <- sequence $ f <$> aa <*> [b] intercalateM f aa' bb