14

“函数式编程仅描述要对程序的输入执行的操作,而不使用临时变量来存储中间结果。”

问题是如何应用函数式编程并使用利用回调的异步模块。在某些情况下,您希望回调访问调用异步引用的函数所构成的变量,但回调的签名已经定义。

例子:

function printSum(file,a){
     //var fs =....
     var c = a+b;
     fs.readFile(file,function cb(err,result){
          print(a+result);///but wait, I can't access a......
     });
}

当然我可以访问a,但这将违反纯函数式编程范式

4

3 回答 3

10
fs.readFile(file, (function cb(err,result){
    print(this.a+result);
}).bind({a: a});

context如果必须,只需将变量和范围注入函数即可。

因为你抱怨 API

fs.readFile(file, (function cb(a, err,result){
    print(a+result);
}).bind(null, a);

这叫做柯里化。这是更多的FP。

于 2011-06-14T22:44:05.627 回答
1

我认为问题在于您误解了使用中间值的含义(或者他们歪曲了它,我没有阅读链接)。考虑函数式语言中的变量是definition某物的,并且该定义不能改变。在函数式编程中使用值/公式的名称是完全可以接受的,只要它们不改变。

function calculate(a,b,c) {
    // here we define an name to (a+b) so that we can use it later
    // there's nothing wrong with this "functionally", since we don't 
    // change it's definition later
    d = a + b;
    return c * d;
}

另一方面,从功能上讲,以下是不行的

function sum(listofvalues) {
    sum = 0;
    foreach value in listofvalues
        // this is bad, since we're re-defining "sum"
        sum += value;
    return sum
}

对于更接近您代码中的内容...考虑您有一个函数调用map that takes a list of things and a function to apply to a thing and returns a new list of things. It's perfectly acceptable to say:

function add_value(amount) {
    amount_to_incr = amount * 2;
    return function(amount, value) {
        // here we're using that "amount" value provided to us
        // the function returned will always return the same value for the same
        // input... its "referentially transparent"
        // and it uses the "intermediate" value of amount_to_incr... however, since 
        // that value doesn't change, it's fine
        return amount_to_incr + value;
    }
}
map [1,2,3] add_value(2) ;// -> [3,4,5]
于 2011-06-15T04:03:19.387 回答
0
function printSum(file, a) {
     //var fs =....
     var c = a + b;
     fs.readFile(file, function cb(err, result, aa = a) {
          print(aa + result);
     });
}

现在使用默认参数,可以将 a 传递给回调。

于 2019-04-26T00:47:37.863 回答