代码之家  ›  专栏  ›  技术社区  ›  Nathan de Vries

“部分函数应用程序”在JavaScript上下文中是否是一个误称?

  •  11
  • Nathan de Vries  · 技术社区  · 16 年前

    我和我的一个朋友正在讨论在javascript中使用currying和部分函数的应用,我们得出了非常不同的结论,即两者是否可行。我提出了 Function.prototype.curry ,这是我们讨论的基础:

    Function.prototype.curry = function() {
        if (!arguments.length) return this;
    
        var args = Array.prototype.slice.apply(arguments);
        var mmm_curry = this, args;
    
        return function() {
            var inner_args = Array.prototype.slice.apply(arguments);
            return mmm_curry.apply(this, args.concat(inner_args));
        }
    
    }
    

    其用途如下:

    var vindaloo = function(a, b) {
        return (a + b);
    }
    
    var karahi = vindaloo.curry(1);
    var masala = karahi(2);
    var gulai = karahi(3);
    
    print(masala);
    print(other);
    

    蜘蛛猴的产量如下:

    $ js curry.js
    3
    4
    

    他的观点是,自从javascript function 基元本身不支持“部分函数应用程序”,引用绑定到变量的函数是完全错误的。 karahi 部分应用。他的论点是当 vindaloo 函数被转换,函数本身被完全应用并返回一个闭包,而不是“部分应用的函数”。

    现在,我的观点是,虽然javascript本身不支持 功能 原语(不像say,ml或haskell),这并不意味着你不能创建语言的高阶函数,它能够封装部分应用函数的概念。此外,尽管“应用”,函数的作用域仍然绑定到它返回的闭包,从而使其保持“部分应用”。

    哪一个是正确的?

    5 回复  |  直到 16 年前
        1
  •  3
  •   Michael Johnson    16 年前

    从技术上讲,您正在创建一个调用原始函数的全新函数。因此,如果我对部分应用函数的理解是正确的,那么这不是部分应用函数。部分应用的函数将更接近于此(请注意,这不是一般的解决方案):

    vindaloo.curry = function(a) {
        return function(b) {
            return a + b;
        };
    };
    

    IIUC,这仍然不是一个部分应用的函数。但它更近了。如果可以检查代码,则真正的部分应用函数实际上会如下所示:

    function karahi(b) {
        return 1 + b;
    };
    

    所以,从技术上讲,你最初的方法 只返回一个在闭包中绑定的函数。我能想到的在javascript中真正部分应用函数的唯一方法是解析函数、应用更改,然后通过eval()运行它。

    但是,您的解决方案是一个很好的将概念实际应用到JavaScript中的应用,因此实际上,即使在技术上不精确,也可以实现目标。

        2
  •  3
  •   Rene Saarsoo    16 年前

    我认为讨论部分函数的应用是完全可以的 在javascript中-如果它像部分应用程序一样工作,那么它必须 做一个。你还能怎么命名?

    你如何 咖喱 函数完成他的目标只是一个实现 细节。以类似的方式,我们可以在ecmascript规范中部分应用, 但是当IE像你那样实现它的时候,你会 没办法知道。

        3
  •  1
  •   Jason Bunting    16 年前

    技术细节对我来说并不重要——如果语义保持不变,并且对于所有意图和目的,函数的作用就好像它实际上是一个部分应用的函数,谁在乎呢?

    我以前对事情很有学问,但担心这些细节最终并不能完成真正的工作。

    我个人用 MochiKit ;它有一个很好的partial()函数,可以帮助创建这样的函数。我喜欢它。

        4
  •  0
  •   Zach    16 年前

    你应该退房 Curried JavaScript Functions . 我还没有完全理解他的咖喱功能,但可能有你的答案。

    编辑:不过,我同意你的评估。

        5
  •  0
  •   risto    8 年前

    他的观点是,由于javascript函数原语本身不支持“部分函数应用程序”

    你可以很优雅地用ES6做咖喱:

    > const add = a => b => a + b
    > const add10 = add(10)
    > [1,2,3].map(add10)
    [ 11, 12, 13 ]