Haskell:使用列表访问索引

时间:2014-03-31 05:50:38

标签: list haskell

我正在创建一个带有布尔函数和两个列表的函数。它需要迭代第一个列表,对于使布尔函数为true的索引返回第二个列表的相应元素。

例如..

filterAB (>0) [-2, -1, 0, 1, 2] [5, 2, 5, 9, 0]

将返回:

[9, 0]

我正在使用findIndices返回第一个列表中正确索引的列表,这些索引使布尔函数为true,这样我就可以使用它们来访问第二个列表的元素。到目前为止,这是我的代码:

filterAB boolFunc listA listB = take listC listB where
listC = findIndices boolFunc listA

不幸的是行

take listC listB

不起作用,因为take函数需要Int类型作为说明符,而listC是type [Int]

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:6)

另一个版本:

filterAB f l1 l2 = map snd $ filter (f . fst) $ zip l1 l2

如果您对$的理解有困难,那么此版本是相同的:

let filterAB f l1 l2 = map snd ( filter (f . fst) ( zip l1 l2 ))

zip取两个列表并将其转换为一个元组列表。例如:

zip [1,2,3,4] ["un", "deux", "trois", "quatre"] == [(1,"un"),(2,"deux"),(3,"trois"),(4,"quatre")]

filter为列表中的每个元素取一个列表和一个返回true的函数并对其进行过滤,它就像你的filterAB,但更简单:

filter (>0) [-1, 2, -2, 3, -3] == [2,3]

fst拿一对并返回第一个元素,所以f。 fst将在元组的第一个元素上应用f。就像那个过滤器(f.fst)一样,只要考虑每个元组的第一个元素,就可以用来过滤元组列表:

filter (odd . fst)  [(1,"un"),(2,"deux"),(3,"trois"),(4,"quatre")] == [(1,"un"),(3,"trois")]

如果你没有得到点,它只是功能组成所以接下来的两行是相同的:

h = f . g
h = f ( g x )

取一对并返回第二个元素。使用map和map允许我们获取元组列表并返回元组的第二个元素的列表:

map snd [(1,"un"),(2,"deux"),(3,"trois"),(4,"quatre")] == ["un","deux","trois","quatre"]

答案 1 :(得分:6)

还使用简单的列表推导...

[ghci] let filterAB f as bs = [ b | (a, b) <- zip as bs, f a]
[ghci] filterAB (>0) [-2,-1,0,1,2] [5,2,5,9,0]
[9,0]
[ghci] 

答案 2 :(得分:1)

试试这个

filterAB f (x:xs) (y:ys)
    | f x = y : filterAB f xs ys
    | otherwise = filterAB f xs ys
filterAB _ _ _ = []

Chapter 3. Defining Types, Streamlining FunctionsReal World Haskell给出了对此处涉及的语法的非常好的解释。


测试:

*Main> filterAB (>0) [-2,-1,0,1,2] [5,2,5,9,0]
[9,0]
*Main> filterAB (>0) [-2,-1,0,1,2] [5,2,5,9]
[9]
*Main> filterAB (>0) [-2,-1,0,1,2] [5,2,5]
[]
*Main> filterAB (>0) [-2,-1,0] [5,2,5,9,0]
[]
*Main>