有没有办法在 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]
]
在我不断努力提高 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]
]