在Haskell中用concat和map实现过滤器
我不明白这个解决办法。 将应用框映射到列表中的所有元素,如果px==True,则将该元素放在单个元素的列表中,然后concat将所有元素统一起来?到底是把一切都统一起来还是一件一件地统一起来在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
谢谢!我希望有人能理解这一点。我们可以想象一下,例如,我们有五个要素:
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]