函数如"when"但返回值?

Sea*_*ess 3 monads haskell applicative maybe

有没有办法更简洁地写这个?我有很多看起来像这样的功能.它们中的每一个都有一些布尔条件,然后返回一个值或Nothing

rootMiddleware :: Application -> Application
rootMiddleware app req respond =
    fromMaybe next . fmap respond $
          serveIndex ["questionnaire"] "../app/answer/answer.html" req
      <|> serveIndex ["survey"] "../app/builder/builder.html" req
      <|> redirect [] "/survey/forms" req

  where
    next = app req respond

serveIndex :: [Text] -> FilePath -> Request -> Maybe Response
serveIndex prefix fp req =
    if prefix `isPrefixOf` pathInfo req
      then Just $ responseFile status200 [("Content-Type", "text/html")] fp Nothing
      else Nothing

redirect :: [Text] -> ByteString -> Request -> Maybe Response
redirect pathParts url req =
    if pathParts == pathInfo req
      then Just $ redirectTo url
      else Nothing
Run Code Online (Sandbox Code Playgroud)

when非常接近,但它不会让你在应用程序中返回一个值.这种情况有同等的东西吗?

dfe*_*uer 9

听起来你正在寻找guard:

guard :: Alternative f => Bool -> f ()
guard c = if c then pure () else empty
Run Code Online (Sandbox Code Playgroud)

然后你可以重写

if c then Just x else Nothing
Run Code Online (Sandbox Code Playgroud)

x <$ guard c
Run Code Online (Sandbox Code Playgroud)

当你不直接去Just考虑时,请考虑一下

guard c *> e
Run Code Online (Sandbox Code Playgroud)

它也适用于do符号.感谢Daniel Wagner的<$表达.

另请注意

fromMaybe x . fmap f
Run Code Online (Sandbox Code Playgroud)

写的更好

maybe x f
Run Code Online (Sandbox Code Playgroud)

  • [`guard`](https://downloads.haskell.org/~ghc/latest/docs/html/libraries/base-4.8.1.0/Control-Monad.html#v:guard)不使用臭名昭着的` fail`.它曾经使用过`mzero`,但是因为它已被推广使用`Alternative`的`empty`. (3认同)