首页 文章

从另一个函数生成一个列表,该函数在Haskell中返回Bool

提问于
浏览
0

我目前正在处理列表列表(我们用它来表示网格) . 我有一个函数接收2个参数(我的网格和4个整数的元组),它返回一个布尔值 .

现在有了一个新函数,我需要生成一个每个元组的列表,它为某个网格返回True . 例如, function1 (1,3,2,2) grid1 将返回 True 所以我需要在列表中获取 (1,3,2,2) .

另一个问题是我有多个条件来尊重我的元组 (a,b,c,d) 的4个整数,例如: 1 <= a < a+c <= n and 1 <= b < b+d <= m 其中 n 是行数(所以长度为网格), m 是列数(所以长度(头部网格)) .

我有想法使用 Map ,但到目前为止,我从未在这种情况下使用它,我尝试的一切都失败了 .

谢谢

1 回答

  • 2

    在Haskell中有两种基本方法可以做到这一点 .

    • 生成满足您列出的constaints的元组流,但不一定根据函数返回true

    • 使用 filter 来列表列表

    或者我们可以尝试避免生成所有冗余数据,只是有类似的东西

    • 使用我们对谓词的了解,首先只生成一个有效元组流

    因为我们确实做了第二次所以我们会选择前者 . 因此,我们首先生成满足constaints 1 <= a < a + c <= n1 <= b < b + d <= m 的所有元组 .

    现在很明显 a[1 .. n] 范围内, b[1 .. m] 范围内 . 此外,对于每个 a ,我们可以在 [a + 1 .. n - a] 中拥有 c ,并且对于每个 b ,我们可以拥有 [b + 1 .. m - b] . 我们将使用Haskell's list comprehensions进行编码,这是一种非常时髦的方式

    allTuples :: Int -> Int -> [(Int, Int, Int, Int)]
    allTuples n m = -- First we take in n, m
      [(a, b, c, d) |
        a <- [1 .. n],
        b <- [1 .. m],
        c <- [a + 1 .. n - a],
        d <- [b + 1 .. m - b]]
    

    这些 <- 将做正确的事情并采取所有可能的组合 . 接下来我们需要做的就是使用filter删除元素 .

    prune :: Grid -> [(Int, Int, Int, Int)] -> [(Int, Int, Int, Int)]
     prune grid tuples = filter (\t -> f grid t) tuples
     -- could have written:
     -- prune grid = filter (f grid)
     -- prune = filter . f
    

    然后我们可以把它们粘在一起,但我会把这最后一步留给你,因为我不确定你将如何在你的应用程序中使用它 . 您还可以将这些步骤合并为单个列表解析:

    allTuples :: Int -> Int -> [(Int, Int, Int, Int)]
    allTuples n m = -- First we take in n, m
      [(a, b, c, d) |
        a <- [1 .. n],
        b <- [1 .. m],
        c <- [a + 1 .. n - a],
        d <- [b + 1 .. m - b],
        f grid (a, b, c, d)]
    

相关问题