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

时间:2016-03-18 15:48:52

标签: list haskell

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

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

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

我有想法使用地图,但到目前为止,我从未在这种情况下使用它,而且我尝试过的一切都失败了。

由于

1 个答案:

答案 0 :(得分:2)

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

  1. 生成满足您列出的constaints的元组流,但不一定根据函数返回true
  2. 使用filter来排列列表
  3. 或者我们可以尝试避免生成所有冗余数据,只需要像

    那样
    1. 使用我们对谓词的了解,首先只生成一个有效元组流
    2. 由于我们正在处理一个任意函数,我们不能真正做第二个,所以我们选择前者。因此,我们首先生成满足constaints 1 <= a < a + c <= n1 <= b < b + d <= m的所有元组。

      现在很明显,a位于[1 .. n]范围内,b位于[1 .. m]范围内。此外,对于每个a,我们可以在c中拥有[a + 1 .. n - a],并且对于每个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)]