我想从Haskell中的一堆其他预定义变量构建一个命令行参数列表。与许多命令行参数的性质一样,这些参数是否存在。
在Haskell中有条件地构建列表是否有一个共同的习惯用法? if-then-else方法感觉相当乏味:
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.
我有类似
的东西onlyIf :: MonadPlus m => a -> Bool -> m a
onlyIf a p = if p then return a else mzero
或
mwhen :: Monoid a => Bool -> a -> a
mwhen p a = if p then a else mempty
记住,然后可以像
一样使用a `onlyIf` opt1 <>
b `onlyIf` opt2 <>
c `onlyIf` opt3
或
mwhen opt1 [a] <>
mwhen opt2 [b] <>
mwhen opt3 [c]
Hoogle在这里并没有什么帮助,当然,可能有更好(/更常见)的方式来做这些事情。
答案 0 :(得分:12)
我喜欢在这种情况下使用concat
列表推导:
concat
[ [a | opt1]
, [b | opt2]
, [c | opt3]
]
如果[a | opt1]
为False,则 opt1
为空列表,否则为仅包含a
的单例列表。
您也可以使用<$
和guard
:
concat
[ a <$ guard opt1
, b <$ guard opt2
, c <$ guard opt3
]
我认为在基地的任何地方都存在onlyIf
功能。
答案 1 :(得分:2)
您可以使用Writer
(请参阅此question)并使用when
代替Maybe
。
但是,使用Maybe
代替条件,结果会更好。