Monad.hs 8.2 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
--
ross's avatar
ross committed
14 15
-- The 'Functor', 'Monad' and 'MonadPlus' classes,
-- with some useful operations on monads.
16 17

module Control.Monad
ross's avatar
ross committed
18 19 20 21 22
    (
    -- * Functor and monad classes

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

    -- ** Naming conventions
    -- $naming

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

31 32 33 34 35 36 37 38 39 40
    , mapM
    , mapM_
    , forM
    , forM_
    , sequence
    , sequence_
    , (=<<)
    , (>=>)
    , (<=<)
    , forever
41
    , void
ross's avatar
ross committed
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_
ross's avatar
ross committed
56 57 58

    -- ** Conditional execution of monadic expressions

59 60 61
    , guard
    , when
    , unless
ross's avatar
ross committed
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
import GHC.List ( zipWith, unzip )
84
import GHC.Num  ( (-) )
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

ross's avatar
ross committed
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

107 108 109 110 111 112
-- | Right-to-left Kleisli composition of monads. @('>=>')@, 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
Don Stewart's avatar
Don Stewart committed
113 114 115 116
(<=<)       :: Monad m => (b -> m c) -> (a -> m b) -> (a -> m c)
(<=<)       = flip (>=>)

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

123 124 125
-- -----------------------------------------------------------------------------
-- Other monad functions

126 127
-- | 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
ross's avatar
ross committed
128
-- data structures or a state-transforming monad.
129
mapAndUnzipM      :: (Applicative m) => (a -> m (b,c)) -> [a] -> m ([b], [c])
130
{-# INLINE mapAndUnzipM #-}
131
mapAndUnzipM f xs =  unzip <$> traverse f xs
132

133 134
-- | The 'zipWithM' function generalizes 'zipWith' to arbitrary applicative functors.
zipWithM          :: (Applicative m) => (a -> b -> m c) -> [a] -> [b] -> m [c]
135
{-# INLINE zipWithM #-}
136
zipWithM f xs ys  =  sequenceA (zipWith f xs ys)
137

138
-- | 'zipWithM_' is the extension of 'zipWithM' which ignores the final result.
139
zipWithM_         :: (Applicative m) => (a -> b -> m c) -> [a] -> [b] -> m ()
140
{-# INLINE zipWithM_ #-}
141
zipWithM_ f xs ys =  sequenceA_ (zipWith f xs ys)
142

143 144
{- | 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
145
the list arguments. This could be an issue where @('>>')@ and the `folded
146 147 148
function' are not commutative.


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

151
==
152

Don Stewart's avatar
Don Stewart committed
153 154 155 156 157
>       do
>         a2 <- f a1 x1
>         a3 <- f a2 x2
>         ...
>         f am xm
158 159

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

Note: 'foldM' is the same as 'foldlM'
162
-}
ross's avatar
ross committed
163

164
foldM          :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
165
{-# INLINABLE foldM #-}
166 167
{-# SPECIALISE foldM :: (a -> b -> IO a) -> a -> [b] -> IO a #-}
{-# SPECIALISE foldM :: (a -> b -> Maybe a) -> a -> [b] -> Maybe a #-}
168
foldM          = foldlM
169

ross's avatar
ross committed
170
-- | Like 'foldM', but discards the result.
171
foldM_         :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m ()
172
{-# INLINABLE foldM_ #-}
173 174
{-# SPECIALISE foldM_ :: (a -> b -> IO a) -> a -> [b] -> IO () #-}
{-# SPECIALISE foldM_ :: (a -> b -> Maybe a) -> a -> [b] -> Maybe () #-}
175
foldM_ f a xs  = foldlM f a xs >> return ()
176

177
{-
Joachim Breitner's avatar
Joachim Breitner committed
178 179
Note [Worker/wrapper transform on replicateM/replicateM_]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
180 181 182 183 184 185 186 187

The implementations of replicateM and replicateM_ both leverage the
worker/wrapper transform. The simpler implementation of replicateM_, as an
example, would be:

    replicateM_ 0 _ = pure ()
    replicateM_ n f = f *> replicateM_ (n - 1) f

Joachim Breitner's avatar
Joachim Breitner committed
188
However, the self-recursive nature of this implementation inhibits inlining,
189 190
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 to
Joachim Breitner's avatar
Joachim Breitner committed
191
inline the entire definition (as happens for foldr, for example) thereby
192 193 194
specialising for the particular action.

For further information, see this Trac comment, which includes side-by-side
Joachim Breitner's avatar
Joachim Breitner committed
195
Core: https://ghc.haskell.org/trac/ghc/ticket/11795#comment:6
196 197
-}

ross's avatar
ross committed
198 199
-- | @'replicateM' n act@ performs the action @n@ times,
-- gathering the results.
200
replicateM        :: (Applicative m) => Int -> m a -> m [a]
201
{-# INLINABLE replicateM #-}
202 203
{-# SPECIALISE replicateM :: Int -> IO a -> IO [a] #-}
{-# SPECIALISE replicateM :: Int -> Maybe a -> Maybe [a] #-}
204 205 206 207 208 209
replicateM cnt0 f =
    loop cnt0
  where
    loop cnt
        | cnt <= 0  = pure []
        | otherwise = liftA2 (:) f (loop (cnt - 1))
210

ross's avatar
ross committed
211
-- | Like 'replicateM', but discards the result.
212
replicateM_       :: (Applicative m) => Int -> m a -> m ()
213
{-# INLINABLE replicateM_ #-}
214 215
{-# SPECIALISE replicateM_ :: Int -> IO a -> IO () #-}
{-# SPECIALISE replicateM_ :: Int -> Maybe a -> Maybe () #-}
216 217 218 219 220 221 222
replicateM_ cnt0 f =
    loop cnt0
  where
    loop cnt
        | cnt <= 0  = pure ()
        | otherwise = f *> loop (cnt - 1)

223

ross's avatar
ross committed
224
-- | The reverse of 'when'.
225
unless            :: (Applicative f) => Bool -> f () -> f ()
226
{-# INLINABLE unless #-}
227 228
{-# SPECIALISE unless :: Bool -> IO () -> IO () #-}
{-# SPECIALISE unless :: Bool -> Maybe () -> Maybe () #-}
229
unless p s        =  if p then pure () else s
ross's avatar
ross committed
230

231 232 233 234
infixl 4 <$!>

-- | Strict version of 'Data.Functor.<$>'.
--
235
-- @since 4.8.0.0
236 237 238 239 240 241 242
(<$!>) :: 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
243

244 245 246 247 248 249 250 251 252 253
-- -----------------------------------------------------------------------------
-- 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
254
{-# INLINABLE mfilter #-}
255 256 257 258
mfilter p ma = do
  a <- ma
  if p a then return a else mzero

ross's avatar
ross committed
259 260
{- $naming

261
The functions in this library use the following naming conventions:
ross's avatar
ross committed
262

ross's avatar
ross committed
263 264
* A postfix \'@M@\' always stands for a function in the Kleisli category:
  The monad type constructor @m@ is added to function results
265
  (modulo currying) and nowhere else.  So, for example,
ross's avatar
ross committed
266 267 268 269

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

ross's avatar
ross committed
270
* A postfix \'@_@\' changes the result type from @(m a)@ to @(m ())@.
271
  Thus, for example:
ross's avatar
ross committed
272

273 274
>  sequence  :: Monad m => [m a] -> m [a]
>  sequence_ :: Monad m => [m a] -> m ()
ross's avatar
ross committed
275

ross's avatar
ross committed
276
* A prefix \'@m@\' generalizes an existing function to a monadic form.
277
  Thus, for example:
ross's avatar
ross committed
278 279 280 281 282

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

-}