Haskell 多参数​​过滤函数

Haskell filter function with multiple parameters

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

我知道我可以这样做来使用 bool 函数来过滤列表:

newList = filter theFunction aList

但是当 theFunction 像这样接受其他参数时会发生什么:

theFunction -> elementOfAList -> Int -> Bool 

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

编辑 -> 为了提供更多信息,如果我想要一个来自 [1..10] 的整数列表,它会通过一个接受两个整数的函数进行过滤,如果 returns true第一个较小,我该怎么做?

在这种情况下,您可以使用部分应用的谓词函数,如下所示

-- 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 的所有元素。通常这会写成filter (< 5) aList,同operator sections(其中(< 5)为一例,绝对等同于flip theFunction 5)。


上面的过滤将使用相同的Inti调用theFunction每个元素x列表 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`

因为 xacc 都用于相同的角色(元组的第一个元素)它们必须是相同的类型。