【问题标题】:Is there a way to generate a series of list comprehensions programmatically in Haskell?有没有办法在 Haskell 中以编程方式生成一系列列表推导?
【发布时间】:2015-10-28 02:54:11
【问题描述】:

在我不断尝试改进 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 ,m后面的数字是子列表的长度,前n - 1个词的边界为相同的上界,而第 n 项以更大的数字为界。

我当然可以手写所有内容,但这并不是特别好的做法。我想知道是否有办法将这些列表生成到特定的最大 m 值。我的直接想法是 Template Haskell,但我对它的了解还不够,无法确定它是否可用。是否有其他解决方案让我无法理解?

在伪 Haskell 中,我正在寻找的方法类似于:

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

主要问题是我不知道如何动态创建 x1、x2 等。

【问题讨论】:

    标签: list haskell list-comprehension


    【解决方案1】:

    这是你要找的吗?

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

    【讨论】:

    • 这很接近,但我需要一个函数来 1) 给我子列表 x1 = x2 = ... xn 和 2) xn 与其他 xs 使用不同的边界。即,mofn 3 5 10 == [ [x1,x2,x3] | x1
    • 但是你想要 x1
    • 在这种特定情况下,所有子列表的第一个值都需要为 2,尽管为每个子列表使用第一个值 1 的解决方案也应该工作,因为更改第一个值 - 或删除1 -- 应该是微不足道的。
    猜你喜欢
    • 2017-02-12
    • 2015-11-24
    • 1970-01-01
    • 1970-01-01
    • 2011-10-12
    • 2014-10-12
    • 2019-08-28
    • 2016-07-31
    • 2015-08-19
    相关资源
    最近更新 更多