I want to build a list of command line args from a bunch of other pre-defined variables in Haskell. As is the nature of many command line parameters, those are either present or not.
Is there a common idiom for conditionally building a list in Haskell? The if–then–else approach feels rather tedious:
import Control.Monad
join [ if opt1 then [a] else []
, if opt2 then [b] else []
, if opt3 then [c] else [] ]
-- gives me back [a, c] or something like that.
I have something like
onlyIf :: MonadPlus m => a -> Bool -> m a
onlyIf a p = if p then return a else mzero
or
mwhen :: Monoid a => Bool -> a -> a
mwhen p a = if p then a else mempty
in mind, which could then be used like
a `onlyIf` opt1 <>
b `onlyIf` opt2 <>
c `onlyIf` opt3
or
mwhen opt1 [a] <>
mwhen opt2 [b] <>
mwhen opt3 [c]
Hoogle is not really helpful here and of course, there may be a much better (/more common) way of doing this stuff.
I like using concat with list comprehensions in that case:
concat
[ [a | opt1]
, [b | opt2]
, [c | opt3]
]
[a | opt1] is the empty list if opt1 is False, otherwise it is a singleton list containing only a.
You can also do it using <$ and guard:
concat
[ a <$ guard opt1
, b <$ guard opt2
, c <$ guard opt3
]
I don't think there exists a onlyIf function anywhere in base.
You can use a Writer (see this question) and use when instead of Maybe.
However using Maybe instead of condition,result can be better.
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