Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function like "when" but returns a value?

Is there a way to write this more concisely? I have many functions that look like this. Each of them has some boolean condition, which then either return a value or 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

when is really close, but it doesn't let you return a value in the applicative. Is there something equivalent for this case?

like image 591
Sean Clark Hess Avatar asked Sep 25 '26 09:09

Sean Clark Hess


1 Answers

It sounds like you're looking for guard:

guard :: Alternative f => Bool -> f ()
guard c = if c then pure () else empty

Then you can rewrite

if c then Just x else Nothing

as

x <$ guard c

When you're not going straight to Just, consider

guard c *> e

which works very well with do notation as well. Thanks to Daniel Wagner for the <$ expression.

Note also that

fromMaybe x . fmap f

is better written

maybe x f
like image 194
dfeuer Avatar answered Sep 27 '26 01:09

dfeuer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!