[英]Generate a list from another function which returns a Bool in Haskell
i'm currently working on lists of lists (which we use to represent a grid). 我目前正在处理列表(我们用来表示网格)的列表。 I have one function which receive 2 arguments (my grid and a tuple of 4 Integers) and it returns a Boolean.
我有一个函数接收2个参数(我的网格和4个整数的元组),并且它返回一个布尔值。
Now with a new function, I need to generate a list of every tuples which returns True for a certain grid. 现在有了一个新函数,我需要生成每个元组的列表,该列表在特定网格中返回True。 For exemple,
function1 (1,3,2,2) grid1
will return True
so I need to get (1,3,2,2)
in my list. 例如,
function1 (1,3,2,2) grid1
将返回True
因此我需要在列表中获取(1,3,2,2)
。
The other problem is that I have multiple conditions to respect for my tuple (a,b,c,d)
of 4 Integers such as : 1 <= a < a+c <= n and 1 <= b < b+d <= m
where n
is the number of lines (so length grid) and m
is the number of columns (so length (head grid)). 另一个问题是我有多个条件要尊重我的4个整数的元组
(a,b,c,d)
,例如: 1 <= a < a+c <= n and 1 <= b < b+d <= m
,其中n
是行数(因此为长度网格), m
为列数(因此为长度(头部网格))。
I had the idea to use map but so far I never used it in such a situation and everything I tried failed. 我有使用地图的想法,但到目前为止,在这种情况下我从未使用过地图,而我尝试的一切都失败了。
Thanks 谢谢
There are two basic approaches for doing this in Haskell. 在Haskell中,有两种基本方法可以做到这一点。
filter
to par down the list filter
缩小列表 Or we can try to avoid generating all that redundant data and just have something like 或者我们可以尝试避免生成所有多余的数据,而只需要
Since we're working with an arbitrary function, we can't really do the second so we'll opt for the former. 由于我们正在使用任意函数,因此我们无法真正执行第二个函数,因此我们选择前一个。 Thus we start by generating all of the tuples satisfying the constaints
1 <= a < a + c <= n
and 1 <= b < b + d <= m
. 因此,我们首先生成满足条件
1 <= a < a + c <= n
和1 <= b < b + d <= m
所有元组。
Now it's clear that a
is in the range [1 .. n]
and b
is in [1 .. m]
. 现在很明显,
a
在[1 .. n]
范围内, b
在[1 .. m]
。 Furthermore, for each a
we can have c
in [a + 1 .. n - a]
and for each b
we can have [b + 1 .. m - b]
. 此外,对于每个
a
我们可以在[a + 1 .. n - a]
具有c
,对于每个b
我们可以具有[b + 1 .. m - b]
。 We'll use Haskell's list comprehensions to encode this is a very snazzy way 我们将使用Haskell的列表推导进行编码,这是一种非常时髦的方法
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]]
Here these <-
will do the right thing and take all possible combinations. 这些
<-
将在这里做正确的事情,并采取所有可能的组合。 Next all we need do is use filter
to remove elements. 接下来,我们需要做的就是使用
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
Then we can glue them together, but I'll leave this final step to you because I'm not sure how you'll use it in your application. 然后,我们可以将它们粘合在一起,但是我将最后一步留给您,因为我不确定您将如何在应用程序中使用它。 You can also merge these steps into a single list comprehension:
您还可以将以下步骤合并为一个列表理解:
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)]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.