JavaScript和Haskell的函数组合

时间:2013-07-17 18:44:01

标签: javascript node.js v8

在JavaScript中,我们可以将function composition定义为使用带有两个函数f和g的函数来生成一个新函数:

function o(f, g) {
  return function(x) {
   return f(g(x));
  }
 }

这看起来很明显,但我的问题是,运行时解释器/编译器实际计算 f(g(x))吗?

假设我们有一些大数据,比如一个包含许多元素的数组,并且先前计算的函数o作为先前计算的 f(g(x))比未组合 f更快(g(x))

或许,在这种情况下, o(f,g)仅仅是 f(g(x))的宏表达式?

如果它是一个宏,或许,性能没有太大的区别?

这可能取决于运行时环境,我对Chrome / node.js的V8引擎特别感兴趣。

Haskell作为懒惰评估策略的语言在理论上构成函数,我是否正确? GHC实际上是否计算构成函数?

2 个答案:

答案 0 :(得分:2)

不,函数调用o(f, g)将完全返回匿名函数:

function (x) {
    return f(g(x));
}

然后,只有当您调用该匿名函数时,g(x)才会执行,然后f将对g(x)的结果执行。每次调用匿名函数gf都会一个接一个地执行。因此,使用组合函数将比在代码中的任何地方手动调用f(g(x))慢一点,因为额外的匿名函数会有轻微的开销。

示例:

function o(f, g){
    return function(x) {
        return f(g(x));
    }
}

function addTo5(x){
    return x + 5;
}

function multiplyBy(x){
    return function(y){
        return x*y;
    }
}

var composed = o(multiplyBy, addTo5);
composed(5)(3); // Slightly slower than multiplyBy(addTo5(5))(3)

jsperf

答案 1 :(得分:0)

在调用o返回的组合函数之前,不会执行任何计算。这个新函数只是跟踪fg是什么,并在您通过x,评估并返回最终结果时调用它们。