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 166 167
{-# INLINEABLE foldM #-}
{-# 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 173 174
{-# INLINEABLE foldM_ #-}
{-# 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 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
{-
Note [Worker/wrapper transform on replicateM/replicateM_
--------------------------------------------------------

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

However, the self-recrusive 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 to
inline the entire definition (as hapens for foldr, for example) thereby
specialising for the particular action.

For further information, see this Trac comment, which includes side-by-side
Core.

https://ghc.haskell.org/trac/ghc/ticket/11795#comment:6

-}

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

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

226

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

234 235 236 237
infixl 4 <$!>

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

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

ross's avatar
ross committed
262 263
{- $naming

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

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

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

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

276 277
>  sequence  :: Monad m => [m a] -> m [a]
>  sequence_ :: Monad m => [m a] -> m ()
ross's avatar
ross committed
278

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

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

-}