【问题标题】:What is this high-order function called?这个高阶函数叫什么?
【发布时间】:2012-11-24 06:20:37
【问题描述】:

我不确定如何调用转换函数的高阶函数,以便它使用数组而不是参数列表。语言解释起来很复杂,所以在 JavaScript 中有一个例子:

sum = function(a,b){ return a+b; };
foo = function(fn){
    return function(arr){
        return fn.apply(fn,arr);
    };
};
different_sum = foo(sum);
log(sum(2,3)); //5
log(different_sum([2,3])); //5

【问题讨论】:

    标签: javascript coding-style functional-programming naming-conventions


    【解决方案1】:

    Scala 函数有一个类似的方法,它接受一个 n 元函数并返回一个将 n 元组作为唯一参数的一元函数。他们调用方法tupled,你可以在documentation for Function5(或任何其他大于1的函数)中看到它。

    【讨论】:

      【解决方案2】:

      在经典的 Javascript: The Good Parts 中,这被称为 apply 调用模式,是 Javascript 中的四种调用模式之一。

      【讨论】:

      • 谢谢,但这并不完全是柯里化。
      • 是的,我认为这就是你最初想要得到的,这就是为什么我注意到你没有保存传入的参数。我不知道有一个特定的名称,但我'如果我找到了,我会更新我的答案。
      • 根据 Crockford 的书更新了答案。
      【解决方案3】:

      似乎没有任何常用的术语。

      Javascript bind method 封装了一个这样的函数调用,并且没有使用特殊术语。

      Prototype bind method 也是如此,但也没有任何术语。

      jQuery proxy method 也是如此,也没有任何术语。

      解释中使用了术语“包装”,但这当然是一个更广泛的术语。

      【讨论】:

      • 这里非常相似,但我认为真正的问题是如何调用一个函数来改变参数的输入类型,这是这些包装函数都没有的。
      【解决方案4】:

      因为您似乎在问“为了便于阅读,我应该如何称呼这个函数?”验证“这是什么类型/分类的功能?”,我会投入两分钱:

      remixInputMethod()
      

      真的,这只是重新连接函数用户与程序交互的方式的问题。我想这样的东西在你想要通过与你希望用户与之交互的方式不同的输入来交互的程序中是有用的。

      this.sum = function(a,b){ return a+b; };
      remixInputMethod = function(fn){
          return function(arr){
              return fn.apply(fn,arr);
          };
      };
      var _sum = remixInputMethod(this.sum);
      
      // Throughout your program, do some more advanced, funky stuff
      var sums = (function buildListOfSums(num){
          var arr = [], output = 0;
          while(num--){
              arr.push(num);
          }
      
          while(arr.length > 2){
              output += _sum([arr[arr.length - 1], arr[arr.length - 2]]);
              arr.pop(arr[arr.length - 1]);
              arr.pop(arr[arr.length - 2]);
          }
          return output;
      }(20));
      console.log(sums);
      
      // But for the user, lets say, who downloaded your API on Github and is using it to
      // build their first webpage for their uncle
      // who thinks they are smarter than bill gates
      sum(1,2);
      

      【讨论】:

        【解决方案5】:

        我称之为variadic function。如果您不熟悉,可变参数函数采用参数列表并允许程序员将它们作为数组进行交互。

        由于 Javascript 不支持可变参数函数,fn.apply(context, args) 是实现它的方式。不过,我认为实际的实现并不重要。

        可变参数函数以几种不同的语言出现,我最喜欢的包括:

        • C- var_args
        • D

        D网站有个不错的介绍:http://dlang.org/function.html(搜索variadic)

        编辑:

        您的示例与可变参数函数完全相反。它不是将 n 个参数作为一个数组与它们进行交互,而是将一个参数数组作为单独的参数与它们交互。

        我仍然认为这实际上与可变参数函数相同,因为它接受可变数量的参数,但它只是改变了您与这些参数交互的方式。

        可能有一个更好的术语,但也许我们可以称之为inverse variadic function

        【讨论】:

        • 我认为 .apply() 是可变参数的,但是这个函数是可变参数函数的用户。不确定这是否完全相同
        • 不完全是。我做了一些编辑来解释我为什么这么认为。基本上,这是在客户端代码中不使用apply的情况下实现变参函数的唯一方法,但效果是一样的。
        • 就 JavaScript 而言,每个函数都是从 Object 构造函数构建的,该构造函数具有 arguments 属性,该属性基本上是传递给构造函数的参数的变量列表。 JavaScript 中的每个函数都有可变数量,不是吗?
        • 嗯,有 Function.prototype.length,因此您可以获得函数的预期数量,但这不会影响arguments 对象中出现的内容。在 Javascript 中,arity 的概念是模糊的......
        • @tjameson - 我想你误解了我的意思。这个函数实际上并没有给你一个扩展的参数列表,因为底层函数(即提供的 sn-p 中的fn)仍然需要与以前相同数量的参数。另一方面,all javascript 函数是可变参数——你可以传入任意多(或尽可能少)的参数,并且它不会抱怨调用(尽管有未定义的变量可能会导致其他问题)。
        猜你喜欢
        • 1970-01-01
        • 2017-12-26
        • 1970-01-01
        • 1970-01-01
        • 2019-05-24
        • 1970-01-01
        • 2013-03-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多