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

Is there a way to generate a series of list comprehensions programmatically in Haskell?

在我不断努力提高 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 <= x2 ... <= 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 等

这是您要找的吗?

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 函数,它 returns 列表的连续尾部。

更新

这是您要找的吗?

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]
]