list - 在 Haskell 中生成一组 bool 变量的所有组合

标签 list haskell list-comprehension monads

我正在尝试使用 Haskell 中的列表单子(monad)。我试图在给定指定 bool 变量的字符串列表的情况下生成所有可能命题的列表。

例如调用:

mapM_ print $ allPropositions ["a","b"]

会产生以下结果:

[("a",True),("b",True)]
[("a",True),("b",False)]
[("a",False),("b",True)]
[("a",False),("b",False)]

我已经成功地使用列表理解和递归以及以下代码来做到这一点

allPropositions :: [String] -> [[(String,Bool)]]
allPropositions [] = [[]]
allPropositions (x:xs) = [(x,True):r | r <- allPropositions xs] ++ [(x,False):r | r <- allPropositions xs]

我正在寻找一种使用类似于以下代码片段的 do 表示法来实现此目的的方法,但输入数量可变。有没有办法做到这一点(嵌套单子(monad),...)?

allPropositions' = do
    a <- [True, False]
    b <- [True, False]
    return([("a",a),("b",b)])

最佳答案

你需要的是sequence::Monad m => [m a] -> m [a]

特别是,对于 [] monad,sequence 接受一个 n 列表,并生成所有 n code>-length 列出一次从每个列表中绘制一个元素。

sequence [ [1,2,3], [4,5], [6] ] = 
   [ [1,4,6], [1,5,6], [2,4,6], [2,5,6], [3,4,6], [3,5,6] ]

这对您的特定情况很有帮助,因为如果您有一个 n 个字符串列表,您可以轻松地生成每个字符串的可能性:

map (\s -> [(s,True), (s,False)] ["a", "b", "c"] = 
   [ [("a", True), ("a", False) ]
   , [("b", True), ("b", False) ]
   , [("c", True), ("c", False) ]
   ]

现在您只需从每个列表中选择一个即可让您的命题为每个变量保存一个真值:

sequence (map (\s -> [(s,True), (s,False)] ["a", "b", "c"]) = 
   [ [("a", True), ("b", True), ("c", True)]
   , [("a", True), ("b", True), ("c", False)]
   , [("a", True), ("b", False), ("c", True)]
   , [("a", True), ("b", False), ("c", False)]
   , [("a", False), ("b", True), ("c", True)]
   , [("a", False), ("b", True), ("c", False)]
   , [("a", False), ("b", False), ("c", True)]
   , [("a", False), ("b", False), ("c", False)]
   ]

sequence (map f xs) 出现的频率足够高,因此有一个名称:

mapM f xs = sequence (map f xs)
-- or, point-free style
mapM f = sequence . map f

所以你想要的功能就是

allPropositions vs = mapM (\v -> [(v,True),(v,False)]) vs
-- or, equivalently
allPropositions = mapM (\v -> [(v,True),(v,False)])
-- or, equivalently
allPropositions = mapM $ \v -> [(v,True),(v,False)]
-- or, equivalently, with -XTupleSections
allPropositions = mapM $ \v -> map (v,) [True, False]

关于list - 在 Haskell 中生成一组 bool 变量的所有组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29711260/

相关文章:

python - 将 Python 列表写入 csv 中的列

javascript - 如何在严格评估的语言中实现 protected 递归?

haskell - 如何在不使用套接字文件的情况下将堆栈指向 docker 守护进程启动?

python-3.x - Pandas:检查一列是否存在于另一列中

list - haskell中的质因数分解

python - 将句子的字符串表示形式列表转换为词汇集

c++ - 如何初始化 <list> 中的对象并在 C++ 中迭代它们?它们是随机存储的吗?

c# - 如何对列表进行排序然后对该列表的子集进行排序

function - Haskell 映射和过滤器

bash - 纯 BASH 中的列表理解?