{-# OPTIONS -fno-implicit-prelude #-} ----------------------------------------------------------------------------- -- | -- Module : Control.Monad -- Copyright : (c) The University of Glasgow 2001 -- License : BSD-style (see the file libraries/base/LICENSE) -- -- Maintainer : libraries@haskell.org -- Stability : provisional -- Portability : portable -- -- The 'Functor', 'Monad' and 'MonadPlus' classes, -- with some useful operations on monads.moduleControl.Monad( -- * Functor and monad classesFunctor(fmap) ,Monad((>>=), (>>),return,fail) ,MonadPlus( -- class context: Monadmzero-- :: (MonadPlus m) => m a ,mplus-- :: (MonadPlus m) => m a -> m a -> m a ) -- * Functions -- ** Naming conventions -- $naming -- ** Basic functions from the "Prelude" ,mapM-- :: (Monad m) => (a -> m b) -> [a] -> m [b] ,mapM_-- :: (Monad m) => (a -> m b) -> [a] -> m () ,sequence-- :: (Monad m) => [m a] -> m [a] ,sequence_-- :: (Monad m) => [m a] -> m () , (=<<) -- :: (Monad m) => (a -> m b) -> m a -> m b -- ** Generalisations of list functions ,join-- :: (Monad m) => m (m a) -> m a ,msum-- :: (MonadPlus m) => [m a] -> m a ,filterM-- :: (Monad m) => (a -> m Bool) -> [a] -> m [a] ,mapAndUnzipM-- :: (Monad m) => (a -> m (b,c)) -> [a] -> m ([b], [c]) ,zipWithM-- :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m [c] ,zipWithM_-- :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m () ,foldM-- :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a ,foldM_-- :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m () ,replicateM-- :: (Monad m) => Int -> m a -> m [a] ,replicateM_-- :: (Monad m) => Int -> m a -> m () ,forM,forM_-- ** Conditional execution of monadic expressions ,guard-- :: (MonadPlus m) => Bool -> m () ,when-- :: (Monad m) => Bool -> m () -> m () ,unless-- :: (Monad m) => Bool -> m () -> m () -- ** Monadic lifting operators -- $lifting ,liftM-- :: (Monad m) => (a -> b) -> (m a -> m b) ,liftM2-- :: (Monad m) => (a -> b -> c) -> (m a -> m b -> m c) ,liftM3-- :: ... ,liftM4-- :: ... ,liftM5-- :: ... ,ap-- :: (Monad m) => m (a -> b) -> m a -> m b , (<=<) )whereimportData.Maybe -- ----------------------------------------------------------------------------- -- |The MonadPlus class definitionclassMonadm=>MonadPlusmwheremzero::mamplus::ma->ma->mainstanceMonadPlus[]wheremzero=[]mplus=(++)instanceMonadPlusMaybewheremzero=NothingNothing`mplus`ys=ysxs`mplus`_ys=xs-- ----------------------------------------------------------------------------- -- Functions mandated by the Preludeguard::(MonadPlusm)=>Bool->m()guardTrue=return()guardFalse=mzero-- This subsumes the list-based filter function.filterM::(Monadm)=>(a->mBool)->[a]->m[a]filterM_[]=return[]filterMp(x:xs)=doflg<-pxys<-filterMpxsreturn(ifflgthenx:yselseys) -- This subsumes the list-based concat function.msum::MonadPlusm=>[ma]->ma{-# INLINE msum #-}msum=foldrmplusmzero-- ----------------------------------------------------------------------------- -- Other monad functions -- | The 'join' function is the conventional monad join operator. It is used to -- remove one level of monadic structure, projecting its bound argument into the -- outer level.join::(Monadm)=>m(ma)->majoinx=x>>=id-- | The 'mapAndUnzipM' function maps its first argument over a list, returning -- the result as a pair of lists. This function is mainly used with complicated -- data structures or a state-transforming monad.mapAndUnzipM::(Monadm)=>(a->m(b,c))->[a]->m([b], [c])mapAndUnzipMfxs=sequence(mapfxs)>>=return.unzip-- | The 'zipWithM' function generalises 'zipWith' to arbitrary monads.zipWithM::(Monadm)=>(a->b->mc)->[a]->[b]->m[c]zipWithMfxsys=sequence(zipWithfxsys) -- | 'zipWithM_' is the extension of 'zipWithM' which ignores the final result.zipWithM_::(Monadm)=>(a->b->mc)->[a]->[b]->m()zipWithM_fxsys=sequence_(zipWithfxsys) {- | The 'foldM' function is analogous to 'foldl', except that its result is encapsulated in a monad. Note that 'foldM' works from left-to-right over the list arguments. This could be an issue where '(>>)' and the `folded function' are not commutative. > foldM f a1 [x1, x2, ..., xm ] == > do > a2 <- f a1 x1 > a3 <- f a2 x2 > ... > f am xm If right-to-left evaluation is required, the input list should be reversed. -}foldM::(Monadm)=>(a->b->ma)->a->[b]->mafoldM_a[]=returnafoldMfa(x:xs)=fax>>=\fax->foldMffaxxsfoldM_::(Monadm)=>(a->b->ma)->a->[b]->m()foldM_faxs=foldMfaxs>>return()replicateM::(Monadm)=>Int->ma->m[a]replicateMnx=sequence(replicatenx)replicateM_::(Monadm)=>Int->ma->m()replicateM_nx=sequence_(replicatenx) {- | Conditional execution of monadic expressions. For example, > when debug (putStr "Debugging\n") will output the string @Debugging\\n@ if the Boolean value @debug@ is 'True', and otherwise do nothing. -}when::(Monadm)=>Bool->m()->m()whenps=ifpthenselsereturn() -- | The reverse of 'when'.unless::(Monadm)=>Bool->m()->m()unlessps=ifpthenreturn()elses{- $lifting The monadic lifting operators promote a function to a monad. The function arguments are scanned left to right. For example, > liftM2 (+) [0,1] [0,2] = [0,2,1,3] > liftM2 (+) (Just 1) Nothing = Nothing -}liftM::(Monadm)=>(a1->r)->ma1->mrliftM2::(Monadm)=>(a1->a2->r)->ma1->ma2->mrliftM3::(Monadm)=>(a1->a2->a3->r)->ma1->ma2->ma3->mrliftM4::(Monadm)=>(a1->a2->a3->a4->r)->ma1->ma2->ma3->ma4->mrliftM5::(Monadm)=>(a1->a2->a3->a4->a5->r)->ma1->ma2->ma3->ma4->ma5->mrliftMfm1=do{x1<-m1;return(fx1) }liftM2fm1m2=do{x1<-m1;x2<-m2;return(fx1x2) }liftM3fm1m2m3=do{x1<-m1;x2<-m2;x3<-m3;return(fx1x2x3) }liftM4fm1m2m3m4=do{x1<-m1;x2<-m2;x3<-m3;x4<-m4;return(fx1x2x3x4) }liftM5fm1m2m3m4m5=do{x1<-m1;x2<-m2;x3<-m3;x4<-m4;x5<-m5;return(fx1x2x3x4x5) } {- | In many situations, the 'liftM' operations can be replaced by uses of 'ap', which promotes function application. > return f `ap` x1 `ap` ... `ap` xn is equivalent to > liftMn f x1 x2 ... xn -}ap::(Monadm)=>m(a->b)->ma->mbap=liftM2idinfixr1<=<m1<=<m2=\x->m1=<<m2xforMxsf=mapMfxsforM_xsf=mapM_fxs{- $naming The functions in this library use the following naming conventions: * A postfix \`M\' always stands for a function in the Kleisli category: @m@ is added to function results (modulo currying) and nowhere else. So, for example, > filter :: (a -> Bool) -> [a] -> [a] > filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a] * A postfix \`_\' changes the result type from @(m a)@ to @(m ())@. Thus (in the "Prelude"): > sequence :: Monad m => [m a] -> m [a] > sequence_ :: Monad m => [m a] -> m () * A prefix \`m\' generalises an existing function to a monadic form. Thus, for example: > sum :: Num a => [a] -> a > msum :: MonadPlus m => [m a] -> m a -}

Index

(HTML for this module was generated on 2015-03-03. About the conversion tool.)