>假设我有以下函数:
function f(x) { return x + 1; }
function g(x) { return x * 2; }
function h() { return 5; }
如何将表达式f(g(h()))
转换为延续传递样式?我知道h
被转换为:
function h(ret) { ret(5); }
但是,我不知道如何将表达式f(g(h()))
转换为CPS。
此外,如果f
采用 2 个参数而不是 1 个参数怎么办?这在 CPS 中会是什么样子?
此外,如果f
和g
根本不接受任何争论怎么办?这在 CPS 中看起来如何?
延续传递风格非常简单。例如,假设您有以下要转换为 CPS 的函数:
function f(x) {
return x + 1;
}
function g(x) {
return x * 2;
}
function h() {
return 3;
}
alert(f(g(h())));
用CPS写的:
function f(k) {
return function (x) {
return k(x + 1);
};
}
function g(k) {
return function (x) {
return k(x * 2);
};
}
function h(k) {
return k(3);
}
h(g(f(alert)));
当f
采用两个参数时:
function f(k) {
return function (x) {
return function (y) {
return k(x + y);
};
};
}
function g(k) {
return function (x) {
return k(x * 2);
};
}
function h(k) {
return k(3);
}
h(h(g(f(alert))));
在f
和g
不接受任何参数的情况下,它们不是函数(在函数的数学意义上)。因此,它们只是常量:
function f(k) {
return k(1);
}
function g(k) {
return k(2);
}
function h(k) {
return k(3);
}
h(alert);
g(alert);
f(alert);
无法使用 CPS 编写常量。想想看:当f
和g
不进行任何争论时,f(g(h()))
真的没有任何意义。最好只写h(), g(), f()
.
延续传球风格与咖喱配合使用时特别好:
var f = curry(function (k, x, y) {
return k(x + y);
});
var g = curry(function (k, x) {
return k(x * 2);
});
function h(k) {
return k(3);
}
h(h(g(f(alert))));
function curry(f, l, a) {
var len = l;
var args = a;
switch (arguments.length) {
case 1: len = f.length;
case 2: args = [];
}
if (args.length + 1 === len) {
return function (a) {
return f.apply(null, args.concat([a]));
};
} else {
return function (a) {
return curry(f, len, args.concat([a]));
};
}
}
希望有帮助。