Monad.hs 7.08 KB
Newer Older
1
{-# LANGUAGE Trustworthy #-}
2
{-# LANGUAGE NoImplicitPrelude #-}
3

4
-----------------------------------------------------------------------------
5
-- |
6 7
-- Module      :  Control.Monad
-- Copyright   :  (c) The University of Glasgow 2001
8
-- License     :  BSD-style (see the file libraries/base/LICENSE)
9
--
10 11 12 13
-- Maintainer  :  libraries@haskell.org
-- Stability   :  provisional
-- Portability :  portable
--
14 15
-- The 'Functor', 'Monad' and 'MonadPlus' classes,
-- with some useful operations on monads.
16 17

module Control.Monad
18 19 20 21 22
    (
    -- * Functor and monad classes

      Functor(fmap)
    , Monad((>>=), (>>), return, fail)
23
    , MonadPlus(mzero, mplus)
24 25 26 27 28
    -- * Functions

    -- ** Naming conventions
    -- $naming

Simon Marlow's avatar
Simon Marlow committed
29
    -- ** Basic @Monad@ functions
30

31 32 33 34 35 36 37 38 39 40
    , mapM
    , mapM_
    , forM
    , forM_
    , sequence
    , sequence_
    , (=<<)
    , (>=>)
    , (<=<)
    , forever
41
    , void
42 43 44

    -- ** Generalisations of list functions

45 46 47 48 49 50 51 52 53 54 55
    , join
    , msum
    , mfilter
    , filterM
    , mapAndUnzipM
    , zipWithM
    , zipWithM_
    , foldM
    , foldM_
    , replicateM
    , replicateM_
56 57 58

    -- ** Conditional execution of monadic expressions

59 60 61
    , guard
    , when
    , unless
62 63 64

    -- ** Monadic lifting operators

65 66 67 68 69
    , liftM
    , liftM2
    , liftM3
    , liftM4
    , liftM5
70

71
    , ap
72

73 74 75
    -- ** Strict monadic functions

    , (<$!>)
76 77
    ) where

78
import Data.Foldable ( Foldable, sequence_, sequenceA_, msum, mapM_, foldlM, forM_ )
quchen's avatar
quchen committed
79
import Data.Functor ( void, (<$>) )
80
import Data.Traversable ( forM, mapM, traverse, sequence, sequenceA )
81

82
import GHC.Base hiding ( mapM, sequence )
83 84
import GHC.Enum ( pred )
import GHC.List ( zipWith, unzip )
85 86 87 88

-- -----------------------------------------------------------------------------
-- Functions mandated by the Prelude

89 90
-- | @'guard' b@ is @'pure' ()@ if @b@ is 'True',
-- and 'empty' if @b@ is 'False'.
91
guard           :: (Alternative f) => Bool -> f ()
92 93
guard True      =  pure ()
guard False     =  empty
94

95
-- | This generalizes the list-based 'filter' function.
96

David Feuer's avatar
David Feuer committed
97
{-# INLINE filterM #-}
98 99
filterM          :: (Applicative m) => (a -> m Bool) -> [a] -> m [a]
filterM p        = foldr (\ x -> liftA2 (\ flg -> if flg then (x:) else id) (p x)) (pure [])
100

Don Stewart's avatar
Don Stewart committed
101 102 103 104 105 106
infixr 1 <=<, >=>

-- | Left-to-right Kleisli composition of monads.
(>=>)       :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)
f >=> g     = \x -> f x >>= g

Simon Marlow's avatar
Simon Marlow committed
107
-- | Right-to-left Kleisli composition of monads. @('>=>')@, with the arguments flipped
Don Stewart's avatar
Don Stewart committed
108 109 110 111
(<=<)       :: Monad m => (b -> m c) -> (a -> m b) -> (a -> m c)
(<=<)       = flip (>=>)

-- | @'forever' act@ repeats the action infinitely.
112
forever     :: (Applicative f) => f a -> f b
113
{-# INLINE forever #-}
114
forever a   = let a' = a *> a' in a'
115 116
-- Use explicit sharing here, as it is prevents a space leak regardless of
-- optimizations.
117

118 119 120
-- -----------------------------------------------------------------------------
-- Other monad functions

121 122
-- | 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
123
-- data structures or a state-transforming monad.
124
mapAndUnzipM      :: (Applicative m) => (a -> m (b,c)) -> [a] -> m ([b], [c])
125
{-# INLINE mapAndUnzipM #-}
126
mapAndUnzipM f xs =  unzip <$> traverse f xs
127

128 129
-- | The 'zipWithM' function generalizes 'zipWith' to arbitrary applicative functors.
zipWithM          :: (Applicative m) => (a -> b -> m c) -> [a] -> [b] -> m [c]
130
{-# INLINE zipWithM #-}
131
zipWithM f xs ys  =  sequenceA (zipWith f xs ys)
132

133
-- | 'zipWithM_' is the extension of 'zipWithM' which ignores the final result.
134
zipWithM_         :: (Applicative m) => (a -> b -> m c) -> [a] -> [b] -> m ()
135
{-# INLINE zipWithM_ #-}
136
zipWithM_ f xs ys =  sequenceA_ (zipWith f xs ys)
137

138 139
{- | 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
Simon Marlow's avatar
Simon Marlow committed
140
the list arguments. This could be an issue where @('>>')@ and the `folded
141 142 143
function' are not commutative.


Simon Marlow's avatar
Simon Marlow committed
144
>       foldM f a1 [x1, x2, ..., xm]
145

146
==
147

Don Stewart's avatar
Don Stewart committed
148 149 150 151 152
>       do
>         a2 <- f a1 x1
>         a3 <- f a2 x2
>         ...
>         f am xm
153 154

If right-to-left evaluation is required, the input list should be reversed.
155 156

Note: 'foldM' is the same as 'foldlM'
157
-}
158

159
foldM          :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
160 161 162
{-# INLINEABLE foldM #-}
{-# SPECIALISE foldM :: (a -> b -> IO a) -> a -> [b] -> IO a #-}
{-# SPECIALISE foldM :: (a -> b -> Maybe a) -> a -> [b] -> Maybe a #-}
163
foldM          = foldlM
164

165
-- | Like 'foldM', but discards the result.
166
foldM_         :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m ()
167 168 169
{-# INLINEABLE foldM_ #-}
{-# SPECIALISE foldM_ :: (a -> b -> IO a) -> a -> [b] -> IO () #-}
{-# SPECIALISE foldM_ :: (a -> b -> Maybe a) -> a -> [b] -> Maybe () #-}
170
foldM_ f a xs  = foldlM f a xs >> return ()
171

172 173
-- | @'replicateM' n act@ performs the action @n@ times,
-- gathering the results.
174
replicateM        :: (Applicative m) => Int -> m a -> m [a]
175 176 177
{-# INLINEABLE replicateM #-}
{-# SPECIALISE replicateM :: Int -> IO a -> IO [a] #-}
{-# SPECIALISE replicateM :: Int -> Maybe a -> Maybe [a] #-}
178 179
replicateM 0 _    = pure []
replicateM n x    = liftA2 (:) x (replicateM (pred n) x)
180

181
-- | Like 'replicateM', but discards the result.
182
replicateM_       :: (Applicative m) => Int -> m a -> m ()
183 184 185
{-# INLINEABLE replicateM_ #-}
{-# SPECIALISE replicateM_ :: Int -> IO a -> IO () #-}
{-# SPECIALISE replicateM_ :: Int -> Maybe a -> Maybe () #-}
186 187
replicateM_ 0 _   = pure ()
replicateM_ n x   = x *> replicateM_ (pred n) x
188

189
-- | The reverse of 'when'.
190
unless            :: (Applicative f) => Bool -> f () -> f ()
191 192 193
{-# INLINEABLE unless #-}
{-# SPECIALISE unless :: Bool -> IO () -> IO () #-}
{-# SPECIALISE unless :: Bool -> Maybe () -> Maybe () #-}
194
unless p s        =  if p then pure () else s
195

196 197 198 199
infixl 4 <$!>

-- | Strict version of 'Data.Functor.<$>'.
--
200
-- @since 4.8.0.0
201 202 203 204 205 206 207
(<$!>) :: Monad m => (a -> b) -> m a -> m b
{-# INLINE (<$!>) #-}
f <$!> m = do
  x <- m
  let z = f x
  z `seq` return z

Don Stewart's avatar
Don Stewart committed
208

209 210 211 212 213 214 215 216 217 218
-- -----------------------------------------------------------------------------
-- Other MonadPlus functions

-- | Direct 'MonadPlus' equivalent of 'filter'
-- @'filter'@ = @(mfilter:: (a -> Bool) -> [a] -> [a]@
-- applicable to any 'MonadPlus', for example
-- @mfilter odd (Just 1) == Just 1@
-- @mfilter odd (Just 2) == Nothing@

mfilter :: (MonadPlus m) => (a -> Bool) -> m a -> m a
219
{-# INLINEABLE mfilter #-}
220 221 222 223
mfilter p ma = do
  a <- ma
  if p a then return a else mzero

224 225
{- $naming

226
The functions in this library use the following naming conventions:
227

228 229
* A postfix \'@M@\' always stands for a function in the Kleisli category:
  The monad type constructor @m@ is added to function results
230
  (modulo currying) and nowhere else.  So, for example,
231 232 233 234

>  filter  ::              (a ->   Bool) -> [a] ->   [a]
>  filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]

235
* A postfix \'@_@\' changes the result type from @(m a)@ to @(m ())@.
236
  Thus, for example:
237

238 239
>  sequence  :: Monad m => [m a] -> m [a]
>  sequence_ :: Monad m => [m a] -> m ()
240

241
* A prefix \'@m@\' generalizes an existing function to a monadic form.
242
  Thus, for example:
243 244 245 246 247

>  sum  :: Num a       => [a]   -> a
>  msum :: MonadPlus m => [m a] -> m a

-}