Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 在Haskell中生成一组布尔变量的所有组合_List_Haskell_List Comprehension_Monads - Fatal编程技术网

List 在Haskell中生成一组布尔变量的所有组合

List 在Haskell中生成一组布尔变量的所有组合,list,haskell,list-comprehension,monads,List,Haskell,List Comprehension,Monads,我正试图在哈斯凯尔的单子列表上低头。我试图生成一个所有可能命题的列表,给定一个指定布尔变量的字符串列表 例如呼叫: mapM_ print $ allPropositions ["a","b"] 将产生以下结果: [("a",True),("b",True)] [("a",True),("b",False)] [("a",False),("b",True)] [("a",False),("b",False)] 我已经通过以下代码使用列表理解和递归实现了这一点 allPropositions

我正试图在哈斯凯尔的单子列表上低头。我试图生成一个所有可能命题的列表,给定一个指定布尔变量的字符串列表

例如呼叫:

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]
allPropositions::[String]->[[(String,Bool)]]
所有命题[]=[[]]

所有命题(x:xs)=[(x,True):r | r您需要的是
sequence::Monad m=>[ma]->m[a]

特别是,对于
[]
单子,
序列
获取
n
列表的列表,并生成所有
n
长度列表,每次从每个列表中提取一个元素

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]

我会这样做:

allPropositions :: [a] -> [[(a, Bool)]]
allPropositions = foldr (\x xs -> (:) <$> [(x,True),(x,False)] <*> xs) [[]]
allPropositions::[a]->[[(a,Bool)]]
allPropositions=foldr(\x xs->(:)[(x,True),(x,False)]xs)[[]
你根本不需要单子的全部力量,你所需要的只是

下面是正在发生的事情:

  • 对于基本情况,结果是
    [[]]
    (即
    所有命题[]=[[]]
  • 对于感应情况,结果为
    ⟦(:)[(x,对),(x,错)]x⟧。请注意,双方括号(即
    ⟦⟧)表示应用程序函子的上下文(在本例中为
    []

  • 虽然rampion的答案是正确的,但它使用了
    sequence
    mapM
    这两种单子函数。然而,正如我前面所说的,在这种情况下,你不需要单子的全部功能。

    如果你不想要单子的全部功能,你仍然可以使用
    sequenceA
    ,这可能不是一种改进,但你可以可以使用
    mapM(翻转贴图[True,False]。(,)
    allPropositions :: [a] -> [[(a, Bool)]]
    allPropositions = foldr (\x xs -> (:) <$> [(x,True),(x,False)] <*> xs) [[]]