gpt4 book ai didi

javascript - Trampoline、递归和惰性求值

转载 作者:行者123 更新时间:2023-11-30 17:35:12 26 4
gpt4 key购买 nike

我正在尝试在 JavaScript 中实现基本的惰性序列。我只使用闭包和延续。这是我到目前为止得到的:

var cons = curry(function(x, y, list){
return list(x, y);
});
var head = function(seq){
return seq(function(x, y){
return x;
});
};
var tail = function(seq){
return seq(function(x, y){
return y();
});
};
var iterate = function(f){
var next = f();
if (next != null) {
return cons(next, function(){
return iterate(f);
});
}
};
var take = curry(function(n, seq){
if (n && seq != null) {
return cons(head(seq), function(){
return take(n - 1, tail(seq));
});
}
});
var doSeq = curry(function(n, f, seq){
while (n-- && seq != null) {
f(head(seq));
seq = tail(seq);
}
});

var rand = iterate(Math.random);
var log = function(x){ console.log(x) };

doSeq(10, log, rand); //=> logs 10 random numbers

我没有发布 curry功能,因为它与问题没有直接关系。

现在破坏交易的是 filter。规范的实现是尾递归的:

var filter = curry(function(f, seq){
if (seq == null) {
return;
}
if (!f(head(seq))) {
return filter(f, tail(seq)); // recursion
}
return cons(head(seq), function(){
return filter(f, tail(seq));
});
});

当我在一个序列上多次运行它时,堆栈最终会爆炸:

Imgur

我知道一个常见的解决方法是使用 trampoline ,这在一个急切的世界中相对容易,但对于惰性序列来说实现它似乎令人生畏。我发现了一个错综复杂的 solution in Scheme ,但我放弃了尝试在 JavaScript 中按原样实现它。

这有看起来那么复杂吗?有没有另一种方法可以通过迭代来解决这个问题?任何关于以理智的方式将 Scheme 代码移植到 JavaScript 的提示?

最佳答案

我认为这应该做到同时仍然很懒惰1:

var filter = curry(function(f, seq){
while (seq != null && !f(head(seq)))
seq = tail(seq);
if (seq == null)
return;
return cons(head(seq), function() {
return filter(f, tail(seq))
});
});

可能更易读:

var filter = curry(function(f, seq){
for (; seq != null; seq = tail(seq))
if ( f(head(seq)) )
return cons(head(seq), function() {
return filter(f, tail(seq))
});
});

1):您对惰性序列的表示似乎无法表达可能为空(尚未确定)的列表

关于javascript - Trampoline、递归和惰性求值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22203579/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com