Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Haskell中用concat和map实现过滤器_Haskell_Functional Programming - Fatal编程技术网

在Haskell中用concat和map实现过滤器

在Haskell中用concat和map实现过滤器,haskell,functional-programming,Haskell,Functional Programming,我不明白这个解决办法。 将应用框映射到列表中的所有元素,如果px==True,则将该元素放在单个元素的列表中,然后concat将所有元素统一起来?到底是把一切都统一起来还是一件一件地统一起来 谢谢!我希望有人能理解这一点。我们可以想象一下,例如,我们有五个要素: filter1 :: (a -> Bool) -> [a] -> [a] filter1 p = concat.map box where box x

我不明白这个解决办法。 将应用框映射到列表中的所有元素,如果px==True,则将该元素放在单个元素的列表中,然后concat将所有元素统一起来?到底是把一切都统一起来还是一件一件地统一起来


谢谢!我希望有人能理解这一点。我们可以想象一下,例如,我们有五个要素:

filter1 :: (a -> Bool) -> [a] -> [a]
filter1 p = concat.map box
              where box x
                    | p x       = [x]
                    | otherwise = []
p
适用于
x2
x3
x5
。然后,我们执行如下映射:

[x1, x2, x3, x4, x5]
由于
p
适用于
x2
x3
x5
,这意味着
box
x1
x4
返回一个空列表,为
x2
x3
x5
返回一个带有原始列表的单例列表,因此:

              map box [x1, x2, x3, x4, x5]
------------------------------------------
= [box x1, box x2, box x3, box x4, box x5]
然后,如果我们应用
concat
,空列表(
[]
)将不会向结果中添加任何元素,因此原始元素将被“过滤掉”,而单例列表的内容(p包含的元素)将被添加到列表中,因此:

  [box x1, box x2, box x3, box x4, box x5]
------------------------------------------
=               [[], [x2], [x3], [], [x5]]
因此,通过将我们想要过滤掉的元素映射到空列表,以及将我们想要保留的元素映射到带有该元素的单例列表,并连接这些元素,我们成功地过滤掉我们不想要的元素。尽管如此,这种过滤方法——如果没有优化的话——也不是很有效,因为我们要对所有需要的元素进行装箱和拆箱


请注意,Haskell是一种惰性语言,因此如果您以某种方式
filter1
某些元素,则不会执行此操作,除非您需要结果。此外,
map
concat
也都是惰性的(就像所有函数一样)。这意味着,例如,如果我们对结果的第i个元素感兴趣,我们将不会计算整个列表。

很难从您的问题中看出您实际上在问什么。请尽量把你的问题说清楚。我将解释函数是如何工作的,希望这个解释能够解决您实际提出的问题


首先,
映射框
应用于输入列表。对于满足谓词
p
x
,每次调用
box
都将返回
[x]
;或空列表,用于不满足谓词的
x
。因此,
映射框
的结果将是空列表和单例列表的列表

让我们考虑一个例子。比如说:

  concat [[], [x2], [x3], [], [x5]]
-----------------------------------
=                      [x2, x3, x5]
然后:

第一个元素
1
被映射到
[1]
,因为
p1==True
。第二个元素
2
被映射到
[]
,因为
p2==False
。等等

之后,
concat
将应用于此列表。它将所有这些小列表连接成一个大列表。在我们的例子中:

map box input_list = [ [1], [], [3], [], [5] ]
你说的“最后还是一个接一个”是什么意思?Haskell使用惰性评估。
map box input_list = [ [1], [], [3], [], [5] ]
concat [ [1], [], [3], [], [5] ] = [1] ++ [] ++ [3] ++ [] ++ [5] = [1,3,5]