diff --git a/libraries/base/Control/Monad.hs b/libraries/base/Control/Monad.hs index 0706c869a096746c250b18ed14e7ea7ff542a20c..3570144bd6970b4626865c24c31c600d11244467 100644 --- a/libraries/base/Control/Monad.hs +++ b/libraries/base/Control/Monad.hs @@ -86,8 +86,47 @@ import GHC.Num ( (-) ) -- ----------------------------------------------------------------------------- -- Functions mandated by the Prelude --- | @'guard' b@ is @'pure' ()@ if @b@ is 'True', --- and 'empty' if @b@ is 'False'. +-- | 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 :: (Alternative f) => Bool -> f () guard True = pure () guard False = empty diff --git a/libraries/base/GHC/Base.hs b/libraries/base/GHC/Base.hs index 052f13fbe6f66b35ef88229bd41b2dcf5ede9f15..2d6e0e4195da823e91c63c0f0109856b91fb5b1f 100644 --- a/libraries/base/GHC/Base.hs +++ b/libraries/base/GHC/Base.hs @@ -880,15 +880,24 @@ instance Alternative Maybe where -- | Monads that also support choice and failure. class (Alternative m, Monad m) => MonadPlus m where - -- | the identity of 'mplus'. It should also satisfy the equations + -- | The identity of 'mplus'. It should also satisfy the equations -- -- > mzero >>= f = mzero -- > v >> mzero = mzero -- + -- The default definition is + -- + -- @ + -- mzero = 'empty' + -- @ mzero :: m a mzero = empty - -- | an associative operation + -- | An associative operation. The default definition is + -- + -- @ + -- mplus = ('<|>') + -- @ mplus :: m a -> m a -> m a mplus = (<|>)