【问题标题】:Generate a list from another function which returns a Bool in Haskell从另一个函数生成一个列表,该函数在 Haskell 中返回一个 Bool
【发布时间】:2016-03-18 15:48:51
【问题描述】:

我目前正在处理列表列表(我们用它来表示网格)。 我有一个函数接收 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 个变量在迭代的简单情况下使用它们。我怎么能用 4 个不同的变量来做到这一点,同时记住我需要测试每一种可能性(所以,不仅是(1,1,1,1),(2,2,2,2),而且是(3, 4,1,2) 以及 (4,3,1,2) 为例),我还需要在某处指定我在原始帖子中陈述的条件。

标签: list haskell


【解决方案1】:

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

  1. 生成满足您列出的约束但不一定根据函数返回 true 的元组流
  2. 使用filter 缩小列表

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

  1. 首先利用我们对谓词的了解只生成一个有效元组流

由于我们使用的是任意函数,因此我们无法真正执行第二个函数,因此我们将选择前者。因此,我们首先生成满足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]]

这些&lt;- 将做正确的事情并采取所有可能的组合。接下来我们需要做的就是使用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)]

【讨论】:

  • 您可以轻松地将过滤集成到理解中。根据过滤器的不同,这甚至可能更有效。
  • @dfeuer 当然,我认为将两者分开在概念上更清晰,并且在这种用法中应该表现相同,因为结果会很好地流动。我已经更新了一个注释
  • 我关于效率的观点是,在枚举之间 粘贴条件可以避免大量的工作浪费。
  • 哦,那是公平的,但这与这里有关吗? @dfeuer
  • 在这种情况下无法知道。
猜你喜欢
  • 1970-01-01
  • 2017-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多