你需要的是sequence :: Monad m => [m a] -> m [a]
.
特别是,对于[]
monad, sequence
获取一个列表n
列出并产生所有n
-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]