我只是想知道我对柯里化(Currying)函数的以下理解是否正确。
我想过滤
列表中 4
的所有元素。我可以这样实现:
filter (>4) [1..10]
(>)
被定义为Ord a => a -> a -> Bool
,这就是为什么它不能用于过滤。(>4)
定义为(Ord a, Num a) => a -> Bool
。函数(>)
现在已柯里化(Currying),并且仍需要一个参数。- 由于2.,
(>4)
可以传递给过滤器。 - 传递给过滤器的每个列表元素都将传递给
(>4)
,过滤器将验证谓词并返回结果。
这是正确的吗?
最佳答案
推理或多或少是正确的。 (>)
是一个带有签名的函数:
(>) :: Ord a => a -> (a -> Bool)
所以它是一个函数(就像 Haskell 中的任何其他函数一样)采用一个参数,并且这里返回一个函数 a -> Bool
.
问题是,如果我们使用filter (>) [1,4,2,5]
,然后我们就调用(>) 1
,这将返回一个函数 a -> Bool
,但是 filter
不能使用它,它需要一个从列表中获取元素并返回 Bool
的函数。 ,不是返回映射到 Bool
的函数的函数.
因此我们可以使用:
filter ((<) 4) [1,4,2,5]
在这里我们执行partial application [Haskell-wiki]的函数。这意味着我们生成一个函数 (<) 4 :: (Num a, Ord a) => a -> Bool
。因此,我们可以使用该函数进行过滤,它将返回 [5]
.
我们还可以创建一个带有 lambda 表达式的函数来“交换”参数的顺序:
filter (<b>\x -> (>) x 4</b>) [1,4,2,5]
此处获取值 x
,因此我们将调用 ((>) x) 4
,这将返回 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 toflip (^) 2
, or more verbosely\x -> x ^ 2
所以我们可以将最后一个表达式重写为:
filter <b>(> 4)</b> [1,4,2,5]
关于Haskell - 过滤器、柯里化(Currying),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62518111/