Extras.hs 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. {-# LANGUAGE ExistentialQuantification #-}
  2. module Control.Monad.Extras (
  3. ifM,
  4. unlessM,
  5. whenM,
  6. intercalateM
  7. )where
  8. import Control.Monad
  9. -- | A version of if with monadic test.
  10. ifM :: Monad m => m Bool -> m a -> m a -> m a
  11. ifM i t e = do
  12. i' <- i
  13. if i' then t else e
  14. -- | A version of unless with monadic test
  15. unlessM :: Monad m => m Bool -> m () -> m ()
  16. unlessM p me = do
  17. p' <- p
  18. unless p' me
  19. -- | A version of when with monadic test
  20. whenM :: Monad m => m Bool -> m () -> m ()
  21. whenM p me = do
  22. p' <- p
  23. when p' me
  24. {- |
  25. Folds the second list with the function applied to the first,
  26. intercalating the evaluation. That is:
  27. intercalateM f -> [a00, a10, a20] -> [b1, b2] = do
  28. a01 <- f a00 b1
  29. a11 <- f a10 b1
  30. a21 <- f a20 b1
  31. a02 <- f a11 b2
  32. a12 <- f a21 b2
  33. a22 <- f a31 b2
  34. return [a02, a12, a22]
  35. Usefull for consuming lazy sequences.
  36. -}
  37. intercalateM :: Monad m => (a -> b -> m a) -> [a] -> [b] -> m [a]
  38. intercalateM _ aa [] = return aa
  39. intercalateM f aa (b:bb) = do
  40. aa' <- sequence $ f <$> aa <*> [b]
  41. intercalateM f aa' bb