{-# LANGUAGE MonadComprehensions #-}
module GHC.Utils.Monad
( Applicative(..)
, (<$>)
, MonadFix(..)
, MonadIO(..)
, zipWith3M, zipWith3M_, zipWith4M, zipWithAndUnzipM
, zipWith3MNE
, mapAndUnzipM, mapAndUnzip3M, mapAndUnzip4M, mapAndUnzip5M
, mapAccumLM
, mapSndM
, concatMapM
, mapMaybeM
, anyM, allM, orM
, foldlM, foldlM_, foldrM
, whenM, unlessM
, filterOutM
, partitionM
) where
import GHC.Prelude
import Control.Monad
import Control.Monad.Fix
import Control.Monad.IO.Class
import Control.Monad.Trans.State.Strict (StateT (..))
import Data.Foldable (sequenceA_, foldlM, foldrM)
import Data.List (unzip4, unzip5, zipWith4)
import Data.List.NonEmpty (NonEmpty (..))
import Data.Tuple (swap)
zipWith3M :: Monad m => (a -> b -> c -> m d) -> [a] -> [b] -> [c] -> m [d]
{-# INLINE zipWith3M #-}
zipWith3M :: 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 = [m d] -> m [d]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
forall (f :: * -> *) a. Applicative f => [f a] -> f [a]
sequenceA ((a -> b -> c -> m d) -> [a] -> [b] -> [c] -> [m d]
forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3 a -> b -> c -> m d
f [a]
xs [b]
ys [c]
zs)
zipWith3M_ :: Monad m => (a -> b -> c -> m d) -> [a] -> [b] -> [c] -> m ()
{-# INLINE zipWith3M_ #-}
zipWith3M_ :: forall (m :: * -> *) a b c d.
Monad m =>
(a -> b -> c -> m d) -> [a] -> [b] -> [c] -> m ()
zipWith3M_ a -> b -> c -> m d
f [a]
xs [b]
ys [c]
zs = [m d] -> m ()
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Applicative f) =>
t (f a) -> f ()
sequenceA_ ((a -> b -> c -> m d) -> [a] -> [b] -> [c] -> [m d]
forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3 a -> b -> c -> m d
f [a]
xs [b]
ys [c]
zs)
zipWith4M :: Monad m => (a -> b -> c -> d -> m e)
-> [a] -> [b] -> [c] -> [d] -> m [e]
{-# INLINE zipWith4M #-}
zipWith4M :: 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]
ws [d]
zs = [m e] -> m [e]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
forall (f :: * -> *) a. Applicative f => [f a] -> f [a]
sequenceA ((a -> b -> c -> d -> m e) -> [a] -> [b] -> [c] -> [d] -> [m e]
forall a b c d e.
(a -> b -> c -> d -> e) -> [a] -> [b] -> [c] -> [d] -> [e]
zipWith4 a -> b -> c -> d -> m e
f [a]
xs [b]
ys [c]
ws [d]
zs)
zipWithAndUnzipM :: Monad m
=> (a -> b -> m (c, d)) -> [a] -> [b] -> m ([c], [d])
{-# INLINABLE zipWithAndUnzipM #-}
zipWithAndUnzipM :: 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
x:[a]
xs) (b
y:[b]
ys)
= do { (c, d) <- a -> b -> m (c, d)
f a
x b
y
; (cs, ds) <- zipWithAndUnzipM f xs ys
; return (c:cs, d:ds) }
zipWithAndUnzipM a -> b -> m (c, d)
_ [a]
_ [b]
_ = ([c], [d]) -> m ([c], [d])
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([], [])
zipWith3MNE :: Monad m
=> (a -> b -> c -> m d)
-> NonEmpty a -> NonEmpty b -> NonEmpty c -> m (NonEmpty d)
zipWith3MNE :: forall (m :: * -> *) a b c d.
Monad m =>
(a -> b -> c -> m d)
-> NonEmpty a -> NonEmpty b -> NonEmpty c -> m (NonEmpty d)
zipWith3MNE a -> b -> c -> m d
f ~(a
x :| [a]
xs) ~(b
y :| [b]
ys) ~(c
z :| [c]
zs)
= do { w <- a -> b -> c -> m d
f a
x b
y c
z
; ws <- zipWith3M f xs ys zs
; return $ w :| ws }
mapAndUnzip3M :: Monad m => (a -> m (b,c,d)) -> [a] -> m ([b],[c],[d])
{-# INLINE mapAndUnzip3M #-}
mapAndUnzip3M :: 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)] -> ([b], [c], [d])
forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3 ([(b, c, d)] -> ([b], [c], [d]))
-> m [(b, c, d)] -> m ([b], [c], [d])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> m (b, c, d)) -> [a] -> m [(b, c, d)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse a -> m (b, c, d)
f [a]
xs
mapAndUnzip4M :: Monad m => (a -> m (b,c,d,e)) -> [a] -> m ([b],[c],[d],[e])
{-# INLINE mapAndUnzip4M #-}
mapAndUnzip4M :: 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)] -> ([b], [c], [d], [e])
forall a b c d. [(a, b, c, d)] -> ([a], [b], [c], [d])
unzip4 ([(b, c, d, e)] -> ([b], [c], [d], [e]))
-> m [(b, c, d, e)] -> m ([b], [c], [d], [e])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> m (b, c, d, e)) -> [a] -> m [(b, c, d, e)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse a -> m (b, c, d, e)
f [a]
xs
mapAndUnzip5M :: Monad m => (a -> m (b,c,d,e,f)) -> [a] -> m ([b],[c],[d],[e],[f])
{-# INLINE mapAndUnzip5M #-}
mapAndUnzip5M :: 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)] -> ([b], [c], [d], [e], [f])
forall a b c d e. [(a, b, c, d, e)] -> ([a], [b], [c], [d], [e])
unzip5 ([(b, c, d, e, f)] -> ([b], [c], [d], [e], [f]))
-> m [(b, c, d, e, f)] -> m ([b], [c], [d], [e], [f])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> m (b, c, d, e, f)) -> [a] -> m [(b, c, d, e, f)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse a -> m (b, c, d, e, f)
f [a]
xs
mapAccumLM :: (Monad m, Traversable t)
=> (acc -> x -> m (acc, y))
-> acc
-> t x
-> m (acc, t y)
{-# INLINE [1] mapAccumLM #-}
mapAccumLM :: forall (m :: * -> *) (t :: * -> *) acc x y.
(Monad m, Traversable t) =>
(acc -> x -> m (acc, y)) -> acc -> t x -> m (acc, t y)
mapAccumLM acc -> x -> m (acc, y)
f acc
s = ((t y, acc) -> (acc, t y)) -> m (t y, acc) -> m (acc, t y)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (t y, acc) -> (acc, t y)
forall a b. (a, b) -> (b, a)
swap (m (t y, acc) -> m (acc, t y))
-> (t x -> m (t y, acc)) -> t x -> m (acc, t y)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (StateT acc m (t y) -> acc -> m (t y, acc))
-> acc -> StateT acc m (t y) -> m (t y, acc)
forall a b c. (a -> b -> c) -> b -> a -> c
flip StateT acc m (t y) -> acc -> m (t y, acc)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT acc
s (StateT acc m (t y) -> m (t y, acc))
-> (t x -> StateT acc m (t y)) -> t x -> m (t y, acc)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (x -> StateT acc m y) -> t x -> StateT acc m (t y)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> t a -> f (t b)
traverse x -> StateT acc m y
f'
where
f' :: x -> StateT acc m y
f' = (acc -> m (y, acc)) -> StateT acc m y
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
StateT ((acc -> m (y, acc)) -> StateT acc m y)
-> (x -> acc -> m (y, acc)) -> x -> StateT acc m y
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((m (acc, y) -> m (y, acc))
-> (acc -> m (acc, y)) -> acc -> m (y, acc)
forall a b. (a -> b) -> (acc -> a) -> acc -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((m (acc, y) -> m (y, acc))
-> (acc -> m (acc, y)) -> acc -> m (y, acc))
-> (((acc, y) -> (y, acc)) -> m (acc, y) -> m (y, acc))
-> ((acc, y) -> (y, acc))
-> (acc -> m (acc, y))
-> acc
-> m (y, acc)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((acc, y) -> (y, acc)) -> m (acc, y) -> m (y, acc)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) (acc, y) -> (y, acc)
forall a b. (a, b) -> (b, a)
swap ((acc -> m (acc, y)) -> acc -> m (y, acc))
-> (x -> acc -> m (acc, y)) -> x -> acc -> m (y, acc)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (acc -> x -> m (acc, y)) -> x -> acc -> m (acc, y)
forall a b c. (a -> b -> c) -> b -> a -> c
flip acc -> x -> m (acc, y)
f
{-# RULES "mapAccumLM/List" mapAccumLM = mapAccumLM_List #-}
{-# RULES "mapAccumLM/NonEmpty" mapAccumLM = mapAccumLM_NonEmpty #-}
mapAccumLM_List
:: Monad m
=> (acc -> x -> m (acc, y))
-> acc -> [x] -> m (acc, [y])
{-# INLINE mapAccumLM_List #-}
mapAccumLM_List :: forall (m :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
mapAccumLM_List acc -> x -> m (acc, y)
f acc
s = acc -> [x] -> m (acc, [y])
go acc
s
where
go :: acc -> [x] -> m (acc, [y])
go acc
s (x
x:[x]
xs) = do
(s1, x') <- acc -> x -> m (acc, y)
f acc
s x
x
(s2, xs') <- go s1 xs
return (s2, x' : xs')
go acc
s [] = (acc, [y]) -> m (acc, [y])
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (acc
s, [])
mapAccumLM_NonEmpty
:: Monad m
=> (acc -> x -> m (acc, y))
-> acc -> NonEmpty x -> m (acc, NonEmpty y)
{-# INLINE mapAccumLM_NonEmpty #-}
mapAccumLM_NonEmpty :: forall (m :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y))
-> acc -> NonEmpty x -> m (acc, NonEmpty y)
mapAccumLM_NonEmpty acc -> x -> m (acc, y)
f acc
s (x
x:|[x]
xs) =
[(acc
s2, y
x'y -> [y] -> NonEmpty y
forall a. a -> [a] -> NonEmpty a
:|[y]
xs') | (acc
s1, y
x') <- acc -> x -> m (acc, y)
f acc
s x
x, (acc
s2, [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_List acc -> x -> m (acc, y)
f acc
s1 [x]
xs]
mapSndM :: (Applicative m, Traversable f) => (b -> m c) -> f (a,b) -> m (f (a,c))
mapSndM :: forall (m :: * -> *) (f :: * -> *) b c a.
(Applicative m, Traversable f) =>
(b -> m c) -> f (a, b) -> m (f (a, c))
mapSndM = ((a, b) -> m (a, c)) -> f (a, b) -> m (f (a, c))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> f a -> f (f b)
traverse (((a, b) -> m (a, c)) -> f (a, b) -> m (f (a, c)))
-> ((b -> m c) -> (a, b) -> m (a, c))
-> (b -> m c)
-> f (a, b)
-> m (f (a, c))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (b -> m c) -> (a, b) -> m (a, c)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> (a, a) -> f (a, b)
traverse
concatMapM :: (Monad m, Traversable f) => (a -> m [b]) -> f a -> m [b]
concatMapM :: forall (m :: * -> *) (f :: * -> *) a b.
(Monad m, Traversable f) =>
(a -> m [b]) -> f a -> m [b]
concatMapM a -> m [b]
f f a
xs = (f [b] -> [b]) -> m (f [b]) -> m [b]
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM f [b] -> [b]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ((a -> m [b]) -> f a -> m (f [b])
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> f a -> m (f b)
mapM a -> m [b]
f f a
xs)
{-# INLINE concatMapM #-}
mapMaybeM :: Applicative m => (a -> m (Maybe b)) -> [a] -> m [b]
mapMaybeM :: forall (m :: * -> *) a b.
Applicative m =>
(a -> m (Maybe b)) -> [a] -> m [b]
mapMaybeM a -> m (Maybe b)
f = (a -> m [b] -> m [b]) -> m [b] -> [a] -> m [b]
forall a b. (a -> b -> b) -> b -> [a] -> 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 a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [])
where g :: a -> m [b] -> m [b]
g a
a = (Maybe b -> [b] -> [b]) -> m (Maybe b) -> m [b] -> m [b]
forall a b c. (a -> b -> c) -> m a -> m b -> m c
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)
anyM :: (Monad m, Foldable f) => (a -> m Bool) -> f a -> m Bool
anyM :: forall (m :: * -> *) (f :: * -> *) a.
(Monad m, Foldable f) =>
(a -> m Bool) -> f a -> m Bool
anyM a -> m Bool
f = (a -> m Bool -> m Bool) -> m Bool -> f a -> m Bool
forall a b. (a -> b -> b) -> b -> f a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (m Bool -> m Bool -> m Bool
forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
orM (m Bool -> m Bool -> m Bool)
-> (a -> m Bool) -> a -> m Bool -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m Bool
f) (Bool -> m Bool
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False)
allM :: (Monad m, Foldable f) => (a -> m Bool) -> f a -> m Bool
allM :: forall (m :: * -> *) (f :: * -> *) a.
(Monad m, Foldable f) =>
(a -> m Bool) -> f a -> m Bool
allM a -> m Bool
f = (a -> m Bool -> m Bool) -> m Bool -> f a -> m Bool
forall a b. (a -> b -> b) -> b -> f a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (m Bool -> m Bool -> m Bool
forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
andM (m Bool -> m Bool -> m Bool)
-> (a -> m Bool) -> a -> m Bool -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m Bool
f) (Bool -> m Bool
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True)
orM :: Monad m => m Bool -> m Bool -> m Bool
orM :: forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
orM m Bool
m1 m Bool
m2 = m Bool
m1 m Bool -> (Bool -> m Bool) -> m Bool
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Bool
x -> if Bool
x then Bool -> m Bool
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True else m Bool
m2
andM :: Monad m => m Bool -> m Bool -> m Bool
andM :: forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
andM m Bool
m1 m Bool
m2 = m Bool
m1 m Bool -> (Bool -> m Bool) -> m Bool
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Bool
x -> if Bool
x then m Bool
m2 else Bool -> m Bool
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
foldlM_ :: (Monad m, Foldable t) => (a -> b -> m a) -> a -> t b -> m ()
foldlM_ :: forall (m :: * -> *) (t :: * -> *) a b.
(Monad m, Foldable t) =>
(a -> b -> m a) -> a -> t b -> m ()
foldlM_ = (a -> b -> m a) -> a -> t b -> m ()
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m ()
foldM_
whenM :: Monad m => m Bool -> m () -> m ()
whenM :: forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenM m Bool
mb m ()
thing = do { b <- m Bool
mb
; when b thing }
unlessM :: Monad m => m Bool -> m () -> m ()
unlessM :: forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
unlessM m Bool
condM m ()
acc = do { cond <- m Bool
condM
; unless cond acc }
filterOutM :: (Applicative m) => (a -> m Bool) -> [a] -> m [a]
filterOutM :: forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterOutM a -> m Bool
p =
(a -> m [a] -> m [a]) -> m [a] -> [a] -> m [a]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\ a
x -> (Bool -> [a] -> [a]) -> m Bool -> m [a] -> m [a]
forall a b c. (a -> b -> c) -> m a -> m b -> m c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (\ 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 a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [])
partitionM :: Monad m => (a -> m Bool) -> [a] -> m ([a], [a])
partitionM :: forall (m :: * -> *) a.
Monad m =>
(a -> m Bool) -> [a] -> m ([a], [a])
partitionM a -> m Bool
_ [] = ([a], [a]) -> m ([a], [a])
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([], [])
partitionM a -> m Bool
f (a
x:[a]
xs) = do
res <- a -> m Bool
f a
x
(as,bs) <- partitionM f xs
pure ([x | res]++as, [x | not res]++bs)