-- | Utilities related to Monad and Applicative classes
--   Mostly for backwards compatibility.

module MonadUtils
        ( Applicative(..)
        , (<$>)

        , MonadFix(..)
        , MonadIO(..)

        , liftIO1, liftIO2, liftIO3, liftIO4

        , zipWith3M, zipWith3M_, zipWith4M, zipWithAndUnzipM
        , mapAndUnzipM, mapAndUnzip3M, mapAndUnzip4M, mapAndUnzip5M
        , mapAccumLM
        , mapSndM
        , concatMapM
        , mapMaybeM
        , fmapMaybeM, fmapEitherM
        , anyM, allM, orM
        , foldlM, foldlM_, foldrM
        , maybeMapM
        , whenM, unlessM
        , filterOutM
        ) where

-------------------------------------------------------------------------------
-- Imports
-------------------------------------------------------------------------------

import GhcPrelude

import Control.Applicative
import Control.Monad
import Control.Monad.Fix
import Control.Monad.IO.Class

-------------------------------------------------------------------------------
-- Lift combinators
--  These are used throughout the compiler
-------------------------------------------------------------------------------

-- | Lift an 'IO' operation with 1 argument into another monad
liftIO1 :: MonadIO m => (a -> IO b) -> a -> m b
liftIO1 :: (a -> IO b) -> a -> m b
liftIO1 = (IO b -> m b) -> (a -> IO b) -> a -> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) IO b -> m b
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO

-- | Lift an 'IO' operation with 2 arguments into another monad
liftIO2 :: MonadIO m => (a -> b -> IO c) -> a -> b -> m c
liftIO2 :: (a -> b -> IO c) -> a -> b -> m c
liftIO2 = (((b -> IO c) -> b -> m c) -> (a -> b -> IO c) -> a -> b -> m c
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.)(((b -> IO c) -> b -> m c) -> (a -> b -> IO c) -> a -> b -> m c)
-> ((IO c -> m c) -> (b -> IO c) -> b -> m c)
-> (IO c -> m c)
-> (a -> b -> IO c)
-> a
-> b
-> m c
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(IO c -> m c) -> (b -> IO c) -> b -> m c
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.)) IO c -> m c
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO

-- | Lift an 'IO' operation with 3 arguments into another monad
liftIO3 :: MonadIO m => (a -> b -> c -> IO d) -> a -> b -> c -> m d
liftIO3 :: (a -> b -> c -> IO d) -> a -> b -> c -> m d
liftIO3 = (((b -> c -> IO d) -> b -> c -> m d)
-> (a -> b -> c -> IO d) -> a -> b -> c -> m d
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.)(((b -> c -> IO d) -> b -> c -> m d)
 -> (a -> b -> c -> IO d) -> a -> b -> c -> m d)
-> ((IO d -> m d) -> (b -> c -> IO d) -> b -> c -> m d)
-> (IO d -> m d)
-> (a -> b -> c -> IO d)
-> a
-> b
-> c
-> m d
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(((c -> IO d) -> c -> m d) -> (b -> c -> IO d) -> b -> c -> m d
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.)(((c -> IO d) -> c -> m d) -> (b -> c -> IO d) -> b -> c -> m d)
-> ((IO d -> m d) -> (c -> IO d) -> c -> m d)
-> (IO d -> m d)
-> (b -> c -> IO d)
-> b
-> c
-> m d
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(IO d -> m d) -> (c -> IO d) -> c -> m d
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.))) IO d -> m d
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO

-- | Lift an 'IO' operation with 4 arguments into another monad
liftIO4 :: MonadIO m => (a -> b -> c -> d -> IO e) -> a -> b -> c -> d -> m e
liftIO4 :: (a -> b -> c -> d -> IO e) -> a -> b -> c -> d -> m e
liftIO4 = ((((b -> c -> d -> IO e) -> b -> c -> d -> m e)
-> (a -> b -> c -> d -> IO e) -> a -> b -> c -> d -> m e
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.)(((b -> c -> d -> IO e) -> b -> c -> d -> m e)
 -> (a -> b -> c -> d -> IO e) -> a -> b -> c -> d -> m e)
-> (((c -> d -> IO e) -> c -> d -> m e)
    -> (b -> c -> d -> IO e) -> b -> c -> d -> m e)
-> ((c -> d -> IO e) -> c -> d -> m e)
-> (a -> b -> c -> d -> IO e)
-> a
-> b
-> c
-> d
-> m e
forall b c a. (b -> c) -> (a -> b) -> a -> c
.((c -> d -> IO e) -> c -> d -> m e)
-> (b -> c -> d -> IO e) -> b -> c -> d -> m e
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.))(((c -> d -> IO e) -> c -> d -> m e)
 -> (a -> b -> c -> d -> IO e) -> a -> b -> c -> d -> m e)
-> ((IO e -> m e) -> (c -> d -> IO e) -> c -> d -> m e)
-> (IO e -> m e)
-> (a -> b -> c -> d -> IO e)
-> a
-> b
-> c
-> d
-> m e
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(((d -> IO e) -> d -> m e) -> (c -> d -> IO e) -> c -> d -> m e
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.)(((d -> IO e) -> d -> m e) -> (c -> d -> IO e) -> c -> d -> m e)
-> ((IO e -> m e) -> (d -> IO e) -> d -> m e)
-> (IO e -> m e)
-> (c -> d -> IO e)
-> c
-> d
-> m e
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(IO e -> m e) -> (d -> IO e) -> d -> m e
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.))) IO e -> m e
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO

-------------------------------------------------------------------------------
-- Common functions
--  These are used throughout the compiler
-------------------------------------------------------------------------------

zipWith3M :: Monad m => (a -> b -> c -> m d) -> [a] -> [b] -> [c] -> m [d]
zipWith3M :: (a -> b -> c -> m d) -> [a] -> [b] -> [c] -> m [d]
zipWith3M _ []     _      _      = [d] -> m [d]
forall (m :: * -> *) a. Monad m => a -> m a
return []
zipWith3M _ _      []     _      = [d] -> m [d]
forall (m :: * -> *) a. Monad m => a -> m a
return []
zipWith3M _ _      _      []     = [d] -> m [d]
forall (m :: * -> *) a. Monad m => a -> m a
return []
zipWith3M f :: a -> b -> c -> m d
f (x :: a
x:xs :: [a]
xs) (y :: b
y:ys :: [b]
ys) (z :: c
z:zs :: [c]
zs)
  = do { d
r  <- a -> b -> c -> m d
f a
x b
y c
z
       ; [d]
rs <- (a -> b -> c -> m d) -> [a] -> [b] -> [c] -> m [d]
forall (m :: * -> *) a b c d.
Monad m =>
(a -> b -> c -> m d) -> [a] -> [b] -> [c] -> m [d]
zipWith3M a -> b -> c -> m d
f [a]
xs [b]
ys [c]
zs
       ; [d] -> m [d]
forall (m :: * -> *) a. Monad m => a -> m a
return ([d] -> m [d]) -> [d] -> m [d]
forall a b. (a -> b) -> a -> b
$ d
rd -> [d] -> [d]
forall a. a -> [a] -> [a]
:[d]
rs
       }

zipWith3M_ :: Monad m => (a -> b -> c -> m d) -> [a] -> [b] -> [c] -> m ()
zipWith3M_ :: (a -> b -> c -> m d) -> [a] -> [b] -> [c] -> m ()
zipWith3M_ f :: a -> b -> c -> m d
f as :: [a]
as bs :: [b]
bs cs :: [c]
cs = do { [d]
_ <- (a -> b -> c -> m d) -> [a] -> [b] -> [c] -> m [d]
forall (m :: * -> *) a b c d.
Monad m =>
(a -> b -> c -> m d) -> [a] -> [b] -> [c] -> m [d]
zipWith3M a -> b -> c -> m d
f [a]
as [b]
bs [c]
cs
                           ; () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return () }

zipWith4M :: Monad m => (a -> b -> c -> d -> m e)
          -> [a] -> [b] -> [c] -> [d] -> m [e]
zipWith4M :: (a -> b -> c -> d -> m e) -> [a] -> [b] -> [c] -> [d] -> m [e]
zipWith4M _ []     _      _      _      = [e] -> m [e]
forall (m :: * -> *) a. Monad m => a -> m a
return []
zipWith4M _ _      []     _      _      = [e] -> m [e]
forall (m :: * -> *) a. Monad m => a -> m a
return []
zipWith4M _ _      _      []     _      = [e] -> m [e]
forall (m :: * -> *) a. Monad m => a -> m a
return []
zipWith4M _ _      _      _      []     = [e] -> m [e]
forall (m :: * -> *) a. Monad m => a -> m a
return []
zipWith4M f :: a -> b -> c -> d -> m e
f (x :: a
x:xs :: [a]
xs) (y :: b
y:ys :: [b]
ys) (z :: c
z:zs :: [c]
zs) (a :: d
a:as :: [d]
as)
  = do { e
r  <- a -> b -> c -> d -> m e
f a
x b
y c
z d
a
       ; [e]
rs <- (a -> b -> c -> d -> m e) -> [a] -> [b] -> [c] -> [d] -> m [e]
forall (m :: * -> *) a b c d e.
Monad m =>
(a -> b -> c -> d -> m e) -> [a] -> [b] -> [c] -> [d] -> m [e]
zipWith4M a -> b -> c -> d -> m e
f [a]
xs [b]
ys [c]
zs [d]
as
       ; [e] -> m [e]
forall (m :: * -> *) a. Monad m => a -> m a
return ([e] -> m [e]) -> [e] -> m [e]
forall a b. (a -> b) -> a -> b
$ e
re -> [e] -> [e]
forall a. a -> [a] -> [a]
:[e]
rs
       }


zipWithAndUnzipM :: Monad m
                 => (a -> b -> m (c, d)) -> [a] -> [b] -> m ([c], [d])
{-# INLINABLE zipWithAndUnzipM #-}
-- See Note [flatten_many performance] in TcFlatten for why this
-- pragma is essential.
zipWithAndUnzipM :: (a -> b -> m (c, d)) -> [a] -> [b] -> m ([c], [d])
zipWithAndUnzipM f :: a -> b -> m (c, d)
f (x :: a
x:xs :: [a]
xs) (y :: b
y:ys :: [b]
ys)
  = do { (c :: c
c, d :: d
d) <- a -> b -> m (c, d)
f a
x b
y
       ; (cs :: [c]
cs, ds :: [d]
ds) <- (a -> b -> m (c, d)) -> [a] -> [b] -> m ([c], [d])
forall (m :: * -> *) a b c d.
Monad m =>
(a -> b -> m (c, d)) -> [a] -> [b] -> m ([c], [d])
zipWithAndUnzipM a -> b -> m (c, d)
f [a]
xs [b]
ys
       ; ([c], [d]) -> m ([c], [d])
forall (m :: * -> *) a. Monad m => a -> m a
return (c
cc -> [c] -> [c]
forall a. a -> [a] -> [a]
:[c]
cs, d
dd -> [d] -> [d]
forall a. a -> [a] -> [a]
:[d]
ds) }
zipWithAndUnzipM _ _ _ = ([c], [d]) -> m ([c], [d])
forall (m :: * -> *) a. Monad m => a -> m a
return ([], [])

-- | mapAndUnzipM for triples
mapAndUnzip3M :: Monad m => (a -> m (b,c,d)) -> [a] -> m ([b],[c],[d])
mapAndUnzip3M :: (a -> m (b, c, d)) -> [a] -> m ([b], [c], [d])
mapAndUnzip3M _ []     = ([b], [c], [d]) -> m ([b], [c], [d])
forall (m :: * -> *) a. Monad m => a -> m a
return ([],[],[])
mapAndUnzip3M f :: a -> m (b, c, d)
f (x :: a
x:xs :: [a]
xs) = do
    (r1 :: b
r1,  r2 :: c
r2,  r3 :: d
r3)  <- a -> m (b, c, d)
f a
x
    (rs1 :: [b]
rs1, rs2 :: [c]
rs2, rs3 :: [d]
rs3) <- (a -> m (b, c, d)) -> [a] -> m ([b], [c], [d])
forall (m :: * -> *) a b c d.
Monad m =>
(a -> m (b, c, d)) -> [a] -> m ([b], [c], [d])
mapAndUnzip3M a -> m (b, c, d)
f [a]
xs
    ([b], [c], [d]) -> m ([b], [c], [d])
forall (m :: * -> *) a. Monad m => a -> m a
return (b
r1b -> [b] -> [b]
forall a. a -> [a] -> [a]
:[b]
rs1, c
r2c -> [c] -> [c]
forall a. a -> [a] -> [a]
:[c]
rs2, d
r3d -> [d] -> [d]
forall a. a -> [a] -> [a]
:[d]
rs3)

mapAndUnzip4M :: Monad m => (a -> m (b,c,d,e)) -> [a] -> m ([b],[c],[d],[e])
mapAndUnzip4M :: (a -> m (b, c, d, e)) -> [a] -> m ([b], [c], [d], [e])
mapAndUnzip4M _ []     = ([b], [c], [d], [e]) -> m ([b], [c], [d], [e])
forall (m :: * -> *) a. Monad m => a -> m a
return ([],[],[],[])
mapAndUnzip4M f :: a -> m (b, c, d, e)
f (x :: a
x:xs :: [a]
xs) = do
    (r1 :: b
r1,  r2 :: c
r2,  r3 :: d
r3,  r4 :: e
r4)  <- a -> m (b, c, d, e)
f a
x
    (rs1 :: [b]
rs1, rs2 :: [c]
rs2, rs3 :: [d]
rs3, rs4 :: [e]
rs4) <- (a -> m (b, c, d, e)) -> [a] -> m ([b], [c], [d], [e])
forall (m :: * -> *) a b c d e.
Monad m =>
(a -> m (b, c, d, e)) -> [a] -> m ([b], [c], [d], [e])
mapAndUnzip4M a -> m (b, c, d, e)
f [a]
xs
    ([b], [c], [d], [e]) -> m ([b], [c], [d], [e])
forall (m :: * -> *) a. Monad m => a -> m a
return (b
r1b -> [b] -> [b]
forall a. a -> [a] -> [a]
:[b]
rs1, c
r2c -> [c] -> [c]
forall a. a -> [a] -> [a]
:[c]
rs2, d
r3d -> [d] -> [d]
forall a. a -> [a] -> [a]
:[d]
rs3, e
r4e -> [e] -> [e]
forall a. a -> [a] -> [a]
:[e]
rs4)

mapAndUnzip5M :: Monad m => (a -> m (b,c,d,e,f)) -> [a] -> m ([b],[c],[d],[e],[f])
mapAndUnzip5M :: (a -> m (b, c, d, e, f)) -> [a] -> m ([b], [c], [d], [e], [f])
mapAndUnzip5M _ [] = ([b], [c], [d], [e], [f]) -> m ([b], [c], [d], [e], [f])
forall (m :: * -> *) a. Monad m => a -> m a
return ([],[],[],[],[])
mapAndUnzip5M f :: a -> m (b, c, d, e, f)
f (x :: a
x:xs :: [a]
xs) = do
    (r1 :: b
r1, r2 :: c
r2, r3 :: d
r3, r4 :: e
r4, r5 :: f
r5)      <- a -> m (b, c, d, e, f)
f a
x
    (rs1 :: [b]
rs1, rs2 :: [c]
rs2, rs3 :: [d]
rs3, rs4 :: [e]
rs4, rs5 :: [f]
rs5) <- (a -> m (b, c, d, e, f)) -> [a] -> m ([b], [c], [d], [e], [f])
forall (m :: * -> *) a b c d e f.
Monad m =>
(a -> m (b, c, d, e, f)) -> [a] -> m ([b], [c], [d], [e], [f])
mapAndUnzip5M a -> m (b, c, d, e, f)
f [a]
xs
    ([b], [c], [d], [e], [f]) -> m ([b], [c], [d], [e], [f])
forall (m :: * -> *) a. Monad m => a -> m a
return (b
r1b -> [b] -> [b]
forall a. a -> [a] -> [a]
:[b]
rs1, c
r2c -> [c] -> [c]
forall a. a -> [a] -> [a]
:[c]
rs2, d
r3d -> [d] -> [d]
forall a. a -> [a] -> [a]
:[d]
rs3, e
r4e -> [e] -> [e]
forall a. a -> [a] -> [a]
:[e]
rs4, f
r5f -> [f] -> [f]
forall a. a -> [a] -> [a]
:[f]
rs5)

-- | Monadic version of mapAccumL
mapAccumLM :: Monad m
            => (acc -> x -> m (acc, y)) -- ^ combining function
            -> acc                      -- ^ initial state
            -> [x]                      -- ^ inputs
            -> m (acc, [y])             -- ^ final state, outputs
mapAccumLM :: (acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
mapAccumLM _ s :: acc
s []     = (acc, [y]) -> m (acc, [y])
forall (m :: * -> *) a. Monad m => a -> m a
return (acc
s, [])
mapAccumLM f :: acc -> x -> m (acc, y)
f s :: acc
s (x :: x
x:xs :: [x]
xs) = do
    (s1 :: acc
s1, x' :: y
x')  <- acc -> x -> m (acc, y)
f acc
s x
x
    (s2 :: acc
s2, xs' :: [y]
xs') <- (acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
forall (m :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
mapAccumLM acc -> x -> m (acc, y)
f acc
s1 [x]
xs
    (acc, [y]) -> m (acc, [y])
forall (m :: * -> *) a. Monad m => a -> m a
return    (acc
s2, y
x' y -> [y] -> [y]
forall a. a -> [a] -> [a]
: [y]
xs')

-- | Monadic version of mapSnd
mapSndM :: Monad m => (b -> m c) -> [(a,b)] -> m [(a,c)]
mapSndM :: (b -> m c) -> [(a, b)] -> m [(a, c)]
mapSndM _ []         = [(a, c)] -> m [(a, c)]
forall (m :: * -> *) a. Monad m => a -> m a
return []
mapSndM f :: b -> m c
f ((a :: a
a,b :: b
b):xs :: [(a, b)]
xs) = do { c
c <- b -> m c
f b
b; [(a, c)]
rs <- (b -> m c) -> [(a, b)] -> m [(a, c)]
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> [(a, b)] -> m [(a, c)]
mapSndM b -> m c
f [(a, b)]
xs; [(a, c)] -> m [(a, c)]
forall (m :: * -> *) a. Monad m => a -> m a
return ((a
a,c
c)(a, c) -> [(a, c)] -> [(a, c)]
forall a. a -> [a] -> [a]
:[(a, c)]
rs) }

-- | Monadic version of concatMap
concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b]
concatMapM :: (a -> m [b]) -> [a] -> m [b]
concatMapM f :: a -> m [b]
f xs :: [a]
xs = ([[b]] -> [b]) -> m [[b]] -> m [b]
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM [[b]] -> [b]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ((a -> m [b]) -> [a] -> m [[b]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM a -> m [b]
f [a]
xs)

-- | Applicative version of mapMaybe
mapMaybeM :: Applicative m => (a -> m (Maybe b)) -> [a] -> m [b]
mapMaybeM :: (a -> m (Maybe b)) -> [a] -> m [b]
mapMaybeM f :: a -> m (Maybe b)
f = (a -> m [b] -> m [b]) -> m [b] -> [a] -> m [b]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> m [b] -> m [b]
g ([b] -> m [b]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [])
  where g :: a -> m [b] -> m [b]
g a :: a
a = (Maybe b -> [b] -> [b]) -> m (Maybe b) -> m [b] -> m [b]
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (([b] -> [b]) -> (b -> [b] -> [b]) -> Maybe b -> [b] -> [b]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [b] -> [b]
forall a. a -> a
id (:)) (a -> m (Maybe b)
f a
a)

-- | Monadic version of fmap
fmapMaybeM :: (Monad m) => (a -> m b) -> Maybe a -> m (Maybe b)
fmapMaybeM :: (a -> m b) -> Maybe a -> m (Maybe b)
fmapMaybeM _ Nothing  = Maybe b -> m (Maybe b)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe b
forall a. Maybe a
Nothing
fmapMaybeM f :: a -> m b
f (Just x :: a
x) = a -> m b
f a
x m b -> (b -> m (Maybe b)) -> m (Maybe b)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Maybe b -> m (Maybe b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe b -> m (Maybe b)) -> (b -> Maybe b) -> b -> m (Maybe b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> Maybe b
forall a. a -> Maybe a
Just)

-- | Monadic version of fmap
fmapEitherM :: Monad m => (a -> m b) -> (c -> m d) -> Either a c -> m (Either b d)
fmapEitherM :: (a -> m b) -> (c -> m d) -> Either a c -> m (Either b d)
fmapEitherM fl :: a -> m b
fl _ (Left  a :: a
a) = a -> m b
fl a
a m b -> (b -> m (Either b d)) -> m (Either b d)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Either b d -> m (Either b d)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either b d -> m (Either b d))
-> (b -> Either b d) -> b -> m (Either b d)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> Either b d
forall a b. a -> Either a b
Left)
fmapEitherM _ fr :: c -> m d
fr (Right b :: c
b) = c -> m d
fr c
b m d -> (d -> m (Either b d)) -> m (Either b d)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Either b d -> m (Either b d)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either b d -> m (Either b d))
-> (d -> Either b d) -> d -> m (Either b d)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. d -> Either b d
forall a b. b -> Either a b
Right)

-- | Monadic version of 'any', aborts the computation at the first @True@ value
anyM :: Monad m => (a -> m Bool) -> [a] -> m Bool
anyM :: (a -> m Bool) -> [a] -> m Bool
anyM _ []     = Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
anyM f :: a -> m Bool
f (x :: a
x:xs :: [a]
xs) = do Bool
b <- a -> m Bool
f a
x
                   if Bool
b then Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
                        else (a -> m Bool) -> [a] -> m Bool
forall (m :: * -> *) a. Monad m => (a -> m Bool) -> [a] -> m Bool
anyM a -> m Bool
f [a]
xs

-- | Monad version of 'all', aborts the computation at the first @False@ value
allM :: Monad m => (a -> m Bool) -> [a] -> m Bool
allM :: (a -> m Bool) -> [a] -> m Bool
allM _ []     = Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
allM f :: a -> m Bool
f (b :: a
b:bs :: [a]
bs) = (a -> m Bool
f a
b) m Bool -> (Bool -> m Bool) -> m Bool
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (\bv :: Bool
bv -> if Bool
bv then (a -> m Bool) -> [a] -> m Bool
forall (m :: * -> *) a. Monad m => (a -> m Bool) -> [a] -> m Bool
allM a -> m Bool
f [a]
bs else Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False)

-- | Monadic version of or
orM :: Monad m => m Bool -> m Bool -> m Bool
orM :: m Bool -> m Bool -> m Bool
orM m1 :: m Bool
m1 m2 :: m Bool
m2 = m Bool
m1 m Bool -> (Bool -> m Bool) -> m Bool
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \x :: Bool
x -> if Bool
x then Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True else m Bool
m2

-- | Monadic version of foldl
foldlM :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
foldlM :: (a -> b -> m a) -> a -> [b] -> m a
foldlM = (a -> b -> m a) -> a -> [b] -> m a
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM

-- | Monadic version of foldl that discards its result
foldlM_ :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m ()
foldlM_ :: (a -> b -> m a) -> a -> [b] -> m ()
foldlM_ = (a -> b -> m a) -> a -> [b] -> m ()
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m ()
foldM_

-- | Monadic version of foldr
foldrM        :: (Monad m) => (b -> a -> m a) -> a -> [b] -> m a
foldrM :: (b -> a -> m a) -> a -> [b] -> m a
foldrM _ z :: a
z []     = a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
z
foldrM k :: b -> a -> m a
k z :: a
z (x :: b
x:xs :: [b]
xs) = do { a
r <- (b -> a -> m a) -> a -> [b] -> m a
forall (m :: * -> *) b a.
Monad m =>
(b -> a -> m a) -> a -> [b] -> m a
foldrM b -> a -> m a
k a
z [b]
xs; b -> a -> m a
k b
x a
r }

-- | Monadic version of fmap specialised for Maybe
maybeMapM :: Monad m => (a -> m b) -> (Maybe a -> m (Maybe b))
maybeMapM :: (a -> m b) -> Maybe a -> m (Maybe b)
maybeMapM _ Nothing  = Maybe b -> m (Maybe b)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe b
forall a. Maybe a
Nothing
maybeMapM m :: a -> m b
m (Just x :: a
x) = (b -> Maybe b) -> m b -> m (Maybe b)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM b -> Maybe b
forall a. a -> Maybe a
Just (m b -> m (Maybe b)) -> m b -> m (Maybe b)
forall a b. (a -> b) -> a -> b
$ a -> m b
m a
x

-- | Monadic version of @when@, taking the condition in the monad
whenM :: Monad m => m Bool -> m () -> m ()
whenM :: m Bool -> m () -> m ()
whenM mb :: m Bool
mb thing :: m ()
thing = do { Bool
b <- m Bool
mb
                    ; Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
b m ()
thing }

-- | Monadic version of @unless@, taking the condition in the monad
unlessM :: Monad m => m Bool -> m () -> m ()
unlessM :: m Bool -> m () -> m ()
unlessM condM :: m Bool
condM acc :: m ()
acc = do { Bool
cond <- m Bool
condM
                       ; Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
cond m ()
acc }

-- | Like 'filterM', only it reverses the sense of the test.
filterOutM :: (Applicative m) => (a -> m Bool) -> [a] -> m [a]
filterOutM :: (a -> m Bool) -> [a] -> m [a]
filterOutM p :: a -> m Bool
p =
  (a -> m [a] -> m [a]) -> m [a] -> [a] -> m [a]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\ x :: a
x -> (Bool -> [a] -> [a]) -> m Bool -> m [a] -> m [a]
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (\ flg :: Bool
flg -> if Bool
flg then [a] -> [a]
forall a. a -> a
id else (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:)) (a -> m Bool
p a
x)) ([a] -> m [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [])