有条件地建立一个清单

时间:2014-07-31 11:21:10

标签: haskell conditional-statements idioms

我想从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在这里并没有什么帮助,当然,可能有更好(/更常见)的方式来做这些事情。

2 个答案:

答案 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代替条件,结果会更好。