guard -package:hxt package:relude
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)
Monadic boolean combinators.
Monadic version of
guard that help to check that a condition
(
Bool) holds inside. Works with
Monads that are also
Alternative.
>>> guardM (Just True)
Just ()
>>> guardM (Just False)
Nothing
>>> guardM Nothing
Nothing
Here some complex but real-life example:
findSomePath :: IO (Maybe FilePath)
somePath :: MaybeT IO FilePath
somePath = do
path <- MaybeT findSomePath
guardM $ liftIO $ doesDirectoryExist path
return path
Either lifts a value into an alternative context or gives a minimal
value depending on a predicate. Works with
Alternatives.
>>> guarded even 3 :: [Int]
[]
>>> guarded even 2 :: [Int]
[2]
>>> guarded (const True) "hello" :: Maybe String
Just "hello"
>>> guarded (const False) "world" :: Maybe String
Nothing
You can use this function to implement smart constructors simpler:
newtype HttpHost = HttpHost
{ unHttpHost :: Text
}
mkHttpHost :: Text -> Maybe HttpHost
mkHttpHost host = HttpHost <$> guarded (not . Text.null) host