Extras.hs 1.1 KB

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