javascript - CoffeeScript 中的 n 元 curry

标签 javascript functional-programming coffeescript

我在玩 CoffeeScript 时发现自己写了以下几行,然后敬畏地看着它们:

compose = (f, g) -> (x) -> f g x
curry = (f) -> (x) -> (y) -> f(x, y)
uncurry = (f) -> (x, y) -> (f x) y

多好,我想!现在,作为练习,我想将 curry 和 uncurry 函数泛化为 n 个参数,以获得类似于此的内容:

curry2 = (f) -> (x) -> (y) -> f(x, y)
curry3 = (f) -> (x) -> (y) -> (z) -> f(x, y, z)
curry4 = (f) -> (x) -> (y) -> (z) -> (t) -> f(x, y, z, t)

对于 uncurry 也是一样的:

uncurry2 =  (f) -> (x, y) -> (f x) y
uncurry3 = (f) -> (x, y, z) -> ((f x) y) z
uncurry4 = (f) -> (x, y, z, t) -> (((f x) y) z) t

编写 n 元 uncurry 并不难:

uncurry = (n) -> (f) -> (args...) ->
    if n == 1
        f args[0]
    else
        ((uncurry n - 1) f args.shift()) args...

另一方面,我想不出如何让 n 元 curry 发挥作用。我想到首先实现一个 curry_list 函数,它是这个套件的概括:

curry_list2 = (f) -> (x) -> [x, y]
curry_list3 = (f) -> (x) -> (z) -> [x, y, z]
curry_list4 = (f) -> (x) -> (z) -> (t) -> [x, y, z, t]

实现如下:

curry_list = (n) ->
    curry_list_accum = (n, accum) ->
        if n
            (x) ->
                accum.push x
                curry_list_accum n - 1, accum
        else
            accum
    curry_list_accum n, []

然后我只需将 curry_list 与函数应用程序组合起来以获得柯里化(Currying)。这就是我试图做的:

curry = (n) ->
    apply_helper = (f) -> (args) -> f args...
    (f) -> compose (apply_helper f), (curry_list n)

但由于某种原因,它不起作用。例如,尝试评估

curry(3)((a,b,c) -> a + b + c)(1)(2)(3)

产生以下错误:

Function.prototype.apply: Arguments list has wrong type

现在,在记下更多笔记后,我明白尝试将 f 与 curry_list 组合起来是不正确的。我确实有直觉,我正在寻找的东西看起来像这个构图,但不完全是那个。我这样想对吗?

最后,什么是正确的实现?

最佳答案

您返回的是 curry(3)((a,b,c) -> a + b + c) 之后的组合函数,而不是累加器。

这意味着 ((args) -> f args...) 正在接收一个函数作为参数,您的代码不会等到参数列表完成后才调用 f.

也许不用组合就可以实现这个?

accumulator = (n, accum, f) ->
    return f accum... if n is 0
    (x) ->
        accum.push x
        accumulator n - 1, accum, f

curry = (n) ->
    (f) -> accumulator n, [], f

curry(3)((a,b,c) -> a + b + c)(1)(2)(3) # 6

关于javascript - CoffeeScript 中的 n 元 curry ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8373367/

相关文章:

scala - 在 Scala 中进行一系列验证的函数式方法

f# - F# "remove a lot of subtle bug"如何来自 OCaml "+"?

node.js - 使用node.js和lazy时了解EOF

jquery - 如何使用 Turbolinks 并为每个页面添加特定的元标记以进行 SEO?

javascript - String.format 不是函数

javascript - 如何使用angular cli升级次要版本的angular

javascript - 使用 rails 3 和 remote => true 设计

javascript - 当我在 Angular 中加载动态组件时,jQuery 不工作

functional-programming - APL - 如何找到字符串向量中最长的单词?

javascript - CoffeeScript 代码覆盖率