Corecursion 意味着在每次迭代中调用自己的数据大于或等于以前的数据。Corecursion 适用于 codata,它们是递归定义的值。不幸的是,值递归在严格评估的语言中是不可能的。不过,我们可以使用显式的 thunk:
const Defer = thunk =>
({get runDefer() {return thunk()}})
const app = f => x => f(x);
const fibs = app(x_ => y_ => {
const go = x => y =>
Defer(() =>
[x, go(y) (x + y)]);
return go(x_) (y_).runDefer;
}) (1) (1);
const take = n => codata => {
const go = ([x, tx], acc, i) =>
i === n
? acc
: go(tx.runDefer, acc.concat(x), i + 1);
return go(codata, [], 0);
};
console.log(
take(10) (fibs));
虽然这按预期工作,但方法似乎很尴尬。尤其是可怕的对元组让我很恼火。有没有更自然的方法来处理 JS 中的 corecursion/codata?