Haskell:如何编写一个函数,生成作为参数传递的任意数量列表的每个组合

时间:2018-04-11 16:03:59

标签: haskell nested-lists

所以我想说我需要一个函数foo,它作为参数,任意数量的列表,并返回列表元素的每个组合。

例如,foo [0,1] [0,1,2]会返回[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2]]

foo [0,1] [0,1] [0,1]将返回[[0,0,0],[0,0,1],[0,1,0],[1,0,0],[1,1,0],[1,0,1]]

我正在考虑以递归方式工作,而对于第二个示例,例如,foo x y = [[a,b]|a <- x, b <- y],实际上是foo (foo [1,0] [1,0]) [0,1]

但我现在遇到的问题是foo返回一个列表列表,所以我给它的参数越多,它将拥有的嵌套列表越多,递归调用就越不起作用。有没有人知道如何处理这样的功能?

我认为使用foo x y是一个好主意,所以我可以在任意数量的列表上递归调用它。所以,如果我有ls = [[0,1],[0,1],[0,1,2],[0,1,2,3],[0,1,2,3,4]] 我会在前两个调用foo然后在下一个调用foo,依此类推。

2 个答案:

答案 0 :(得分:3)

如果您将所有输入包装在列表foo==sequence

e.g。

> sequence [[0,1], [0,1,2]]

[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2]]

答案 1 :(得分:2)

这是sequenceAsequence。 (前者使用[a]的Applicative实例,而后者使用[a]的Monad实例,但在这种情况下它们是相同的)。两者都是根据traverse定义的,但我们自己定义它:

foo = foldr f (pure [])
  where
  f x ys = (:) <$> x <*> ys