Movatterモバイル変換
[0]ホーム
{-# LANGUAGE Trustworthy #-}{-# LANGUAGE NoImplicitPrelude #-}------------------------------------------------------------------------------- |-- 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(mzero,mplus)-- * Functions-- ** Naming conventions-- $naming-- ** Basic @Monad@ functions,mapM,mapM_,forM,forM_,sequence,sequence_,(=<<),(>=>),(<=<),forever,void-- ** Generalisations of list functions,join,msum,mfilter,filterM,mapAndUnzipM,zipWithM,zipWithM_,foldM,foldM_,replicateM,replicateM_-- ** Conditional execution of monadic expressions,guard,when,unless-- ** Monadic lifting operators,liftM,liftM2,liftM3,liftM4,liftM5,ap-- ** Strict monadic functions,(<$!>))whereimportData.Foldable(Foldable,sequence_,sequenceA_,msum,mapM_,foldlM,forM_)importData.Functor(void,(<$>))importData.Traversable(forM,mapM,traverse,sequence,sequenceA)importGHC.Basehiding(mapM,sequence)importGHC.List(zipWith,unzip)importGHC.Num((-))-- ------------------------------------------------------------------------------- Functions mandated by the Prelude-- | Conditional failure of 'Alternative' computations. Defined by---- @-- guard True = 'pure' ()-- guard False = 'empty'-- @---- ==== __Examples__---- Common uses of 'guard' include conditionally signaling an error in-- an error monad and conditionally rejecting the current choice in an-- 'Alternative'-based parser.---- As an example of signaling an error in the error monad 'Maybe',-- consider a safe division function @safeDiv x y@ that returns-- 'Nothing' when the denominator @y@ is zero and @'Just' (x \`div\`-- y)@ otherwise. For example:---- @-- >>> safeDiv 4 0-- Nothing-- >>> safeDiv 4 2-- Just 2-- @---- A definition of @safeDiv@ using guards, but not 'guard':---- @-- safeDiv :: Int -> Int -> Maybe Int-- safeDiv x y | y /= 0 = Just (x \`div\` y)-- | otherwise = Nothing-- @---- A definition of @safeDiv@ using 'guard' and 'Monad' @do@-notation:---- @-- safeDiv :: Int -> Int -> Maybe Int-- safeDiv x y = do-- guard (y /= 0)-- return (x \`div\` y)-- @guard::(Alternativef)=>Bool->f()guardTrue=pure()guardFalse=empty-- | This generalizes the list-based 'filter' function.{-# INLINEfilterM#-}filterM::(Applicativem)=>(a->mBool)->[a]->m[a]filterMp=foldr(\x->liftA2(\flg->ifflgthen(x:)elseid)(px))(pure[])infixr1<=<,>=>-- | Left-to-right composition of Kleisli arrows.(>=>)::Monadm=>(a->mb)->(b->mc)->(a->mc)f>=>g=\x->fx>>=g-- | Right-to-left composition of Kleisli arrows. @('>=>')@, with the arguments-- flipped.---- Note how this operator resembles function composition @('.')@:---- > (.) :: (b -> c) -> (a -> b) -> a -> c-- > (<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c(<=<)::Monadm=>(b->mc)->(a->mb)->(a->mc)(<=<)=flip(>=>)-- | Repeat an action indefinitely.---- ==== __Examples__---- A common use of 'forever' is to process input from network sockets,-- 'System.IO.Handle's, and channels-- (e.g. 'Control.Concurrent.MVar.MVar' and-- 'Control.Concurrent.Chan.Chan').---- For example, here is how we might implement an [echo-- server](https://en.wikipedia.org/wiki/Echo_Protocol), using-- 'forever' both to listen for client connections on a network socket-- and to echo client input on client connection handles:---- @-- echoServer :: Socket -> IO ()-- echoServer socket = 'forever' $ do-- client <- accept socket-- 'Control.Concurrent.forkFinally' (echo client) (\\_ -> hClose client)-- where-- echo :: Handle -> IO ()-- echo client = 'forever' $-- hGetLine client >>= hPutStrLn client-- @forever::(Applicativef)=>fa->fb{-# INLINEforever#-}forevera=leta'=a*>a'ina'-- Use explicit sharing here, as it prevents a space leak regardless of-- optimizations.-- ------------------------------------------------------------------------------- Other monad functions-- | 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::(Applicativem)=>(a->m(b,c))->[a]->m([b],[c]){-# INLINEmapAndUnzipM#-}mapAndUnzipMfxs=unzip<$>traversefxs-- | The 'zipWithM' function generalizes 'zipWith' to arbitrary applicative functors.zipWithM::(Applicativem)=>(a->b->mc)->[a]->[b]->m[c]{-# INLINEzipWithM#-}zipWithMfxsys=sequenceA(zipWithfxsys)-- | 'zipWithM_' is the extension of 'zipWithM' which ignores the final result.zipWithM_::(Applicativem)=>(a->b->mc)->[a]->[b]->m(){-# INLINEzipWithM_#-}zipWithM_fxsys=sequenceA_(zipWithfxsys){- | The 'foldM' function is analogous to 'foldl', except that its result isencapsulated in a monad. Note that 'foldM' works from left-to-right overthe list arguments. This could be an issue where @('>>')@ and the `foldedfunction' are not commutative.> foldM f a1 [x1, x2, ..., xm]>> ==>> do> a2 <- f a1 x1> a3 <- f a2 x2> ...> f am xmIf right-to-left evaluation is required, the input list should be reversed.Note: 'foldM' is the same as 'foldlM'-}foldM::(Foldablet,Monadm)=>(b->a->mb)->b->ta->mb{-# INLINABLEfoldM#-}{-# SPECIALISEfoldM::(a->b->IOa)->a->[b]->IOa#-}{-# SPECIALISEfoldM::(a->b->Maybea)->a->[b]->Maybea#-}foldM=foldlM-- | Like 'foldM', but discards the result.foldM_::(Foldablet,Monadm)=>(b->a->mb)->b->ta->m(){-# INLINABLEfoldM_#-}{-# SPECIALISEfoldM_::(a->b->IOa)->a->[b]->IO()#-}{-# SPECIALISEfoldM_::(a->b->Maybea)->a->[b]->Maybe()#-}foldM_faxs=foldlMfaxs>>return(){-Note [Worker/wrapper transform on replicateM/replicateM_]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~The implementations of replicateM and replicateM_ both leverage theworker/wrapper transform. The simpler implementation of replicateM_, as anexample, would be: replicateM_ 0 _ = pure () replicateM_ n f = f *> replicateM_ (n - 1) fHowever, the self-recursive nature of this implementation inhibits inlining,which means we never get to specialise to the action (`f` in the code above).By contrast, the implementation below with a local loop makes it possible toinline the entire definition (as happens for foldr, for example) therebyspecialising for the particular action.For further information, see this Trac comment, which includes side-by-sideCore: https://ghc.haskell.org/trac/ghc/ticket/11795#comment:6-}-- | @'replicateM' n act@ performs the action @n@ times,-- gathering the results.replicateM::(Applicativem)=>Int->ma->m[a]{-# INLINABLEreplicateM#-}{-# SPECIALISEreplicateM::Int->IOa->IO[a]#-}{-# SPECIALISEreplicateM::Int->Maybea->Maybe[a]#-}replicateMcnt0f=loopcnt0whereloopcnt|cnt<=0=pure[]|otherwise=liftA2(:)f(loop(cnt-1))-- | Like 'replicateM', but discards the result.replicateM_::(Applicativem)=>Int->ma->m(){-# INLINABLEreplicateM_#-}{-# SPECIALISEreplicateM_::Int->IOa->IO()#-}{-# SPECIALISEreplicateM_::Int->Maybea->Maybe()#-}replicateM_cnt0f=loopcnt0whereloopcnt|cnt<=0=pure()|otherwise=f*>loop(cnt-1)-- | The reverse of 'when'.unless::(Applicativef)=>Bool->f()->f(){-# INLINABLEunless#-}{-# SPECIALISEunless::Bool->IO()->IO()#-}{-# SPECIALISEunless::Bool->Maybe()->Maybe()#-}unlessps=ifpthenpure()elsesinfixl4<$!>-- | Strict version of 'Data.Functor.<$>'.---- @since 4.8.0.0(<$!>)::Monadm=>(a->b)->ma->mb{-# INLINE(<$!>)#-}f<$!>m=dox<-mletz=fxz`seq`returnz-- ------------------------------------------------------------------------------- Other MonadPlus functions-- | Direct 'MonadPlus' equivalent of 'Data.List.filter'.---- ==== __Examples__---- The 'Data.List.filter' function is just 'mfilter' specialized to-- the list monad:---- @-- 'Data.List.filter' = ( 'mfilter' :: (a -> Bool) -> [a] -> [a] )-- @---- An example using 'mfilter' with the 'Maybe' monad:---- @-- >>> mfilter odd (Just 1)-- Just 1-- >>> mfilter odd (Just 2)-- Nothing-- @mfilter::(MonadPlusm)=>(a->Bool)->ma->ma{-# INLINABLEmfilter#-}mfilterpma=doa<-maifpathenreturnaelsemzero{- $namingThe functions in this library use the following naming conventions:* A postfix \'@M@\' always stands for a function in the Kleisli category: The monad type constructor @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, for example:> sequence :: Monad m => [m a] -> m [a]> sequence_ :: Monad m => [m a] -> m ()* A prefix \'@m@\' generalizes an existing function to a monadic form. Thus, for example:> filter :: (a -> Bool) -> [a] -> [a]> mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a-}
[8]ページ先頭