我目前正在处理列表列表(我们用它来表示网格)。 我有一个函数接收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
是列数(所以长度(头部网格))。
我有想法使用地图,但到目前为止,我从未在这种情况下使用它,而且我尝试过的一切都失败了。
由于
答案 0 :(得分:2)
在Haskell中有两种基本方法可以做到这一点。
filter
来排列列表或者我们可以尝试避免生成所有冗余数据,只需要像
那样由于我们正在处理一个任意函数,我们不能真正做第二个,所以我们选择前者。因此,我们首先生成满足constaints 1 <= a < a + c <= n
和1 <= 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)]