有没有办法在Haskell中以编程方式生成一系列列表推导?

时间:2015-10-28 02:54:11

标签: list haskell list-comprehension

在我不断努力改善Haskell的过程中,我试图解决一个问题,我想创建一系列这种形式的列表理解:

m2 = [[x1,x2] | x1 <- [2..110], x2 <- [x1..111]]
m3 = [[x1,x2,x3] | x1 <- [2..22], x2 <- [x1..22], x3 <- [x2..24]]
m4 = [[x1,x2,x3,x4] | x1 <- [2..10], x2 <- [x1..10], x3 <- [x2..10], x4 <- [x3..12]]
...

其中 x1&lt; = x2 ...&lt; = xn ,m后面的数字是子列表的长度,第一个 n - 1 项是由相同的上限界定,而第n个术语以更大的数字为界。

我当然可以手工编写所有内容,但这并不是特别好的做法。我想知道是否有办法生成这些列表达到特定的最大m值。我的直接想法是模板Haskell,但我不太了解它以确定它是否可用。是否有其他解决方案可以逃避我?

在伪Haskell中,我正在寻找的是一些类似的方法:

mOfN n bound term = [ [x1..xn] | x1 <- [2..bound], x2 <- [x1..bound], ..., xn <- [x(n-1)..term] ]

主要问题是我无法弄清楚如何动态创建x1,x2等。

1 个答案:

答案 0 :(得分:4)

这是你在找什么?

import Data.List (tails)

mofn 0 xs = [ [] ]
mofn m xs = [ y:zs | (y:ys) <- tails xs, zs <- mofn (m-1) ys ]

即。 mofn 3 [1..5]是:

[[1,2,3],[1,2,4],[1,2,5],[1,3,4],[1,3,5],[1,4,5],[2,3,4],[2,3,5],[2,4,5],[3,4,5]]

键是tails函数,它返回列表的连续尾部。

<强>更新

这是你在找什么?

mofn' 1 lo hi bnd = [ [x] | x <- [lo..bnd] ]
mofn' k lo hi bnd = [ x:ys | x <- [lo..hi], ys <- mofn' (k-1) x hi bnd ]

mofn' 3 1 3 5是:

[[1,1,1], [1,1,2], [1,1,3], [1,1,4], [1,1,5],
 [1,2,2], [1,2,3], [1,2,4], [1,2,5],
 [1,3,3], [1,3,4], [1,3,5],
 [2,2,2], [2,2,3], [2,2,4], [2,2,5],
 [2,3,3], [2,3,4], [2,3,5],
 [3,3,3], [3,3,4], [3,3,5]
]