在Haskell中列出理解

时间:2011-05-12 18:24:29

标签: haskell list-comprehension

我一直在使用以下代码来获取预定数量的所有组合:

getList x = [ [a,b,c] | a <- [1..x], b <- [1..x], c <- [1..x]]

这开始很好,但我希望扩展程序以处理非常大的列表,我一直认为必须有更好的方法来执行此操作。我如何创建一个与此处采用相同参数x的函数,以及该子列表具有多少项的另一个参数。对于四个项目,我会去修改代码:

getList x = [ [a,b,c,d] | a <- [1..x], b <- [1..x], c <- [1..x], d <- [1..x]]

它不需要是列表理解。谢谢你的帮助。

2 个答案:

答案 0 :(得分:17)

我相信你想要的是replicateM中的Control.Monad功能。

列表monad基于“尝试所有可能的组合”,而普通replicate通过重复项目多次来创建列表。因此,replicateM的结果是,给出一些可能的值列表,列出了从该列表中选择项目的所有可能方法的次数。

例如:

> replicateM 2 [0, 1]
[[0,0],[0,1],[1,0],[1,1]]
> replicateM 3 [0, 1]
[[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]]

所以要将你的函数扩展到任意重复,你可以使用类似的东西:

getListN n x = replicateM n [1..x]

...您的原始getList等同于getListN 3

答案 1 :(得分:3)

如果有人喜欢非Monadic解决方案来理解内部工作原理(尽管通过replicateM解决问题很棒!):

getListN n = foldl (\ass bs -> [ b:as | b <- bs, as <- ass]) [[]] . replicate n

基本上,通过foldl实现此功能的方式与replacatM - 解决方案完全相同。