Haskell中的snd函数如何在过滤器中工作

时间:2019-06-23 07:25:05

标签: list haskell filter filtering predicate

我将此代码输入ghci

Prelude> filter snd [('a',True),('b',True),('c',False),('d',True)]

为什么返回

[('a',True),('b',True),('d',True)]

而不是

[('a',True),('c',False),('d',True)]

snd函数返回第二个项目,那么为什么不filter snd过滤第二个项目呢?

3 个答案:

答案 0 :(得分:8)

您希望<h1 class="title"> {{ json.SCREENS.DETAILS.TITLE }} </h1> 从该表达式的colloquial sense的列表中“过滤”元素,并因此filter删除第二个项目。

那不是它的工作原理

如果您是对的,则filter snd将得出filter snd [1,2,3]。相反,它不会进行类型检查,因为[1,3]适用于元组而不适用于数字。

那么,它如何工作?

snd返回filter f [item1, item2, ...]item的所有f item的列表

例如,True返回filter even [1,2,3,4]

由于[2,4]的值为snd ('b', True),在您的示例中,True将在结果中包含filter。同样,(b, True)将被省略

答案 1 :(得分:7)

简而言之from itertools import count def get_nth_index(lst, item, n): c = count(1) return next((i for i, x in enumerate(lst) if x == item and next(c) == n), None) a = [9,8,2,3,8,3,5] indx = get_nth_index(a, 8, 2) if indx is not None: del a[indx] print(a) # [9, 8, 2, 3, 3, 5] 保留2个元组,其中元组的第二项是filter snd

filter :: (a -> Bool) -> [a] -> [a]以将类型True的元素映射到a的函数作为参数。如果BoolBool,它将在结果中保留原始列表的元素,否则该元素将不属于结果。

True因此按 elementwise 过滤: not 不会考虑列表中的下一个或上一个元素。它只是检查元素上的谓词是否满足。

由于您这里有一个2元组的列表,其中每个元组的第二项是filter,因此snd :: (a, b) -> b会将每个元素映射到第二个元素上,从而保留2元组其中2元组的第二项是Bool。因此,True的最通用类型是filter snd,因为2元组的第二项应该是filter snd :: [(a, Bool)] -> [(a, Bool)]

因此,这意味着Bool的过滤方式确实如下:

filter snd

我们可以使用显式递归来过滤掉第二个元素,例如:

Prelude> filter snd [('a',True),('b',True),('c',False),('d',True)]
[('a',True),('b',True),('d',True)]

例如:

filterAtEven :: [a] -> [a]
filterAtEven [] = []
filterAtEven (x:xs) = x : filterAtOdd xs

filterAtOdd :: [a] -> [a]
filterAtOdd [] = []
filterAtOdd (_:xs) = filterAtEven xs

或者,如果您要删除特定的索引,我们可以使用deleteAt :: Int -> [a] -> [a]包中的ilist

Prelude> filterAtEven [('a',True),('b',True),('c',False),('d',True)]
[('a',True),('c',False)]
Prelude> filterAtOdd [('a',True),('b',True),('c',False),('d',True)]
[('b',True),('d',True)]

或者我们可以自己实现:

Prelude> import Data.List.Index
Prelude Data.List.Index> deleteAt 2 [('a',True),('b',True),('c',False),('d',True)]
[('a',True),('b',True),('d',True)]

答案 2 :(得分:4)

您的filter函数根据每对的第二个值过滤列表。这就是('c',False)被过滤掉的原因...