{-# LANGUAGE CPP #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE Trustworthy #-} {-# LANGUAGE TypeFamilies #-} module Monad ( module Export , Monad ((>>=), return) , MonadFail (fail) , MonadPlus (..) , (=<<) , (>=>) , (<=<) , (>>) , forever , join , mfilter , filterM , mapAndUnzipM , zipWithM , zipWithM_ , foldM , foldM_ , replicateM , replicateM_ , concatMapM , concatForM , guard , when , unless , allM , anyM , andM , orM , liftM , liftM2 , liftM3 , liftM4 , liftM5 , ap , (<$!>) ) where import Monad.Either as Export import Monad.Maybe as Export import Monad.Trans as Export import Base (IO, seq) import Control.Applicative (Applicative (pure)) import Data.Function ((.)) import Data.Functor (fmap) import Data.Traversable (Traversable (traverse)) import Prelude (Bool (..), flip) #if __GLASGOW_HASKELL__ >= 710 import Control.Monad hiding (fail, (<$!>)) #else import Control.Monad hiding (fail) #endif #if __GLASGOW_HASKELL__ >= 800 import Control.Monad.Fail (MonadFail (..)) #else import Prelude (Maybe (Nothing), String) import qualified Prelude as P (fail) import Text.ParserCombinators.ReadP (ReadP) import Text.ParserCombinators.ReadPrec (ReadPrec) #endif import Containers (Element, NontrivialContainer, toList) -- old specialized to list version -- concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b] -- | Lifting bind into a monad. Generalized version of @concatMap@ -- that works with a monadic predicate. concatMapM :: (Applicative q, Monad m, Traversable m) => (a -> q (m b)) -> m a -> q (m b) concatMapM f = fmap join . traverse f {-# INLINE concatMapM #-} -- | Like 'concatMapM', but has its arguments flipped, so can be used -- instead of the common @fmap concat $ forM@ pattern. concatForM :: (Applicative q, Monad m, Traversable m) => m a -> (a -> q (m b)) -> q (m b) concatForM = flip concatMapM {-# INLINE concatForM #-} (<$!>) :: Monad m => (a -> b) -> m a -> m b f <$!> m = do x <- m let z = f x z `seq` return z {-# INLINE (<$!>) #-} andM :: (NontrivialContainer f, Element f ~ m Bool, Monad m) => f -> m Bool andM = go . toList where go [] = pure True go (p:ps) = do q <- p if q then go ps else pure False orM :: (NontrivialContainer f, Element f ~ m Bool, Monad m) => f -> m Bool orM = go . toList where go [] = pure False go (p:ps) = do q <- p if q then pure True else go ps allM :: (NontrivialContainer f, Monad m) => (Element f -> m Bool) -> f -> m Bool allM p = go . toList where go [] = pure True go (x:xs) = do q <- p x if q then go xs else pure False anyM :: (NontrivialContainer f, Monad m) => (Element f -> m Bool) -> f -> m Bool anyM p = go . toList where go [] = pure False go (x:xs) = do q <- p x if q then pure True else go xs {-# SPECIALIZE andM :: [IO Bool] -> IO Bool #-} {-# SPECIALIZE orM :: [IO Bool] -> IO Bool #-} {-# SPECIALIZE anyM :: (a -> IO Bool) -> [a] -> IO Bool #-} {-# SPECIALIZE allM :: (a -> IO Bool) -> [a] -> IO Bool #-} -- Copied from 'fail' by Herbert Valerio Riedel (the library is under BSD3) #if __GLASGOW_HASKELL__ < 800 class Monad m => MonadFail m where fail :: String -> m a instance MonadFail Maybe where fail _ = Nothing instance MonadFail [] where fail _ = [] instance MonadFail IO where fail = P.fail instance MonadFail ReadPrec where fail = P.fail -- = P (\_ -> fail s) instance MonadFail ReadP where fail = P.fail #endif