"currying allows abstraction over arity" 是什么意思?

What does "currying allows abstraction over arity" mean?

在 Javascript 中寻找函数式编程的好处时,我遇到了以下 Haskell 示例:

(.) :: (b -> c) -> (a -> b) -> a -> c

据说类型变量c可以是一个函数类型,这样这个函数就可以在它的参数参数列表的某个前缀上工作。我不知道 Haskell 但这显然只是函数组合。在这种情况下,对 arity 的抽象意味着什么?它以何种方式成为优势?有人可以使用 Javascript 示例向我简要解释一下吗?

是的,这个只是函数组合。他们的意思是 (.) 可以用于任何这些类型(以及其他类型),第一个是最通用的:

(.) :: (b -> c) -> (a -> b) -> a -> c
(.) :: (b -> c -> d) -> (a -> b) -> a -> c -> d
(.) :: (b -> c -> d -> e) -> (a -> b) -> a -> c -> d -> e
...

这是给你的脑筋急转弯。 (.) . (.)的类型是什么,组合函数与自身的组合?

组合函数实际上可能不是最有启发性的例子。如果你再研究Haskell,你会遇到其他的,比如组合动作结果的"applicative style"。例如,

getLine

从标准输入读取一行。

(,) <$> getLine <*> getLine

读取两个并将它们捆绑成一对。

(,,) <$> getLine <*> getLine <*> getLine

读取三个并将它们捆绑成一个三元组。这一切都有效,因为运算符是左结合的,并不关心所有的函数。例如,最后一个例子等同于

(((,,) <$> getLine) <*> getLine) <*> getLine

它将 (,,) 映射到 getLine 操作上,生成一个读取一行并生成两个参数的函数的操作。该操作应用于 getLine,产生一个读取两行并生成一个参数的函数的操作。最后,将其应用于 getLine,生成读取三行并生成三元组的操作。