“currying允许抽象超过arity”是什么意思?

时间:2016-03-15 20:16:32

标签: haskell currying

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

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

据说类型变量c可以是函数类型,因此该函数可以在其参数的参数列表的某个前缀上运行。我不知道Haskell,但这显然只是功能组合。在这种情况下,对于arity的抽象意味着什么,以及它在哪种方式中具有优势?有人可以通过使用Javascript示例向我简单解释一下吗?

1 个答案:

答案 0 :(得分:9)

是的,这个只是功能组合。他们提出的观点是(.)可以用于任何这些类型(其中包括),其中第一个是最常见的:

(.) :: (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,你会遇到其他人,比如结合行动结果的“应用风格”。例如,

getLine

从标准输入读取一行。

(,) <$> getLine <*> getLine

读取两个并将它们捆绑在一起。

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

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

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

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