Haskell - 过滤、柯里化

Haskell - Filter, Currying

我只想知道我对柯里化函数的以下理解是否正确。 我想 filter 列表中的所有元素 > 4。我可以这样实现:

filter (>4) [1..10]
  1. (>)定义为Ord a => a -> a -> Bool,这就是为什么它不能被低音过滤的原因。
  2. (>4) 定义为 (Ord a, Num a) => a -> Bool。函数 (>) 现在已柯里化,仍然需要一个参数。
  3. 因为2.,(>4)可以传递给过滤器
  4. 传递给过滤器的每个列表元素都将传递给 (>4),并且过滤器将验证谓词和 return 结果。

这是正确的吗?

这个推理或多或少是正确的。 (>) 是一个带有签名的函数:

(>) :: Ord a => a -> (a -> Bool)

所以它是一个函数(与 Haskell 中的任何其他函数一样)采用 一个 参数,这里 return 是一个函数 a -> Bool.

因此问题是,如果我们使用 filter (>) [1,4,2,5],那么我们将调用 (>) 1,这将因此 return 一个函数 a -> Bool,但是filter 不能与之一起使用,它需要一个从列表中获取元素的函数,并且 return 是一个 Bool,而不是 return 映射函数的函数Bool.

因此我们可以使用:

filter ((<) 4) [1,4,2,5]

这里我们执行partial application [Haskell-wiki]的功能。因此,这意味着我们生成了一个函数 (<) 4 :: (Num a, Ord a) => a -> Bool。因此我们可以使用该函数进行过滤,因此它将 return [5].

我们也可以用lambda表达式创建一个函数来“交换”参数的顺序:

filter (<b>\x -> (>) x 4</b>) [1,4,2,5]

这里对于一个值 x,我们将因此调用 ((>) x) 4,这将因此 return 一个 Bool.

由于经常发生中缀运算符的两侧之一被提供一个值,Haskell 有 sectioning syntax for an infix operator [Haskell-wiki]:

  • (2^) (left section) is equivalent to (^) 2, or more verbosely \x -> 2 ^ x;
  • (^2) (right section) is equivalent to flip (^) 2, or more verbosely \x -> x ^ 2

所以我们可以将最后一个表达式重写为:

filter <b>(> 4)</b> [1,4,2,5]