具有多个参数的Haskell过滤器函数

时间:2017-10-08 15:34:34

标签: haskell filter parameters predicate partial-application

我正在尝试学习Haskell,并想知道如何过滤给定列表,使用带有多个参数的函数,将列表中的每个元素与其他不变元素一起传递给函数,以创建新列表。

据我所知,我可以使用bool函数来过滤列表:

newList = filter theFunction aList

但是当theFunction采用其他参数时会发生什么:

theFunction -> elementOfAList -> Int -> Bool 

然后如何过滤列表中的每个元素,同时在另一个元素中解析函数?任何帮助将不胜感激:)

编辑 - >为了提供更多信息,如果我想要一个[1..10]的整数列表,那么通过一个带两个整数的函数进行过滤,如果第一个整数较小则返回true,我怎么能这样做? / p>

1 个答案:

答案 0 :(得分:1)

在这种情况下,您使用部分应用的谓词函数,如此

-- theFunction :: elementOfAList -> Int -> Bool       -- "::" means, "is of type"
newList = filter (flip theFunction i) aList

,因为

flip theFunction i x = theFunction x i

根据flip的定义,flip theFunction的类型为Int -> elementOfAList -> Bool

flip ::       (a -> b   -> c   ) -> b -> a -> c
theFunction :: a -> Int -> Bool
flip theFunction ::               Int -> a -> Bool
flip theFunction  (i ::  Int)         :: a -> Bool

其中i是其他地方定义的Int值。 a是一个类型变量,即它可以是任何类型,如列表元素的类型(即对于列表aList :: [a],每个元素具有相同的类型,a )。

例如,使用theFunction x i = x < i,您可以调用filter (flip theFunction 5) aList,在结果列表中保留aList小于5的所有元素。通常这只会写为{{ 1}},operator sections(其中filter (< 5) aList是一个示例,绝对等同于(< 5))。

以上过滤将在列表flip theFunction 5的每个元素Int调用i时使用相同的theFunctionx }。如果你想重新计算aList,那就用另一种模式(即高阶函数)来完成,

Int

假设您希望在mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y]) 找到所有元素时保留所有元素的列表。然后你可以像

那样做
theFunction

因为theFunction :: elementOfAList -> Int -> Bool foo :: Int -> [Int] -> [Int] foo i xs = concat (snd (mapAccumL g i xs)) -- normally written as -- concat $ snd $ mapAccumL g i xs -- or -- concat . snd $ mapAccumL g i xs -- or even -- concat . snd . mapAccumL g i $ xs where g acc x -- g :: (acc -> x -> (acc, y)) according to mapAccumL's signature | theFunction x acc = (x, [x]) -- include `x` in output, and update the acc | otherwise = (acc, []) -- keep the accumulated value, and skip this `x` x都用在同一个角色(元组的第一个元素)中,所以它们必须是相同的类型。