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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With