Javascript 如何在严格评估的设置中编码corecursion/codata?

Javascript 如何在严格评估的设置中编码corecursion/codata?,javascript,functional-programming,lazy-evaluation,corecursion,codata,Javascript,Functional Programming,Lazy Evaluation,Corecursion,Codata,Corecursion意味着在每次迭代中调用大于或等于以前的数据。Corecursion在codata上工作,codata是递归定义的值。不幸的是,在严格求值的语言中,值递归是不可能的。不过,我们可以使用显式thunks: const Defer=thunk=> ({get runDefer(){return thunk()}}) 常数app=f=>x=>f(x); 常数fibs=app(x=>y=>{ 常数go=x=>y=> 延迟(()=> [x,go(y)(x+y)]; 返回go(x_)(

Corecursion意味着在每次迭代中调用大于或等于以前的数据。Corecursion在codata上工作,codata是递归定义的值。不幸的是,在严格求值的语言中,值递归是不可能的。不过,我们可以使用显式thunks:

const Defer=thunk=>
({get runDefer(){return thunk()}})
常数app=f=>x=>f(x);
常数fibs=app(x=>y=>{
常数go=x=>y=>
延迟(()=>
[x,go(y)(x+y)];
返回go(x_)(y_).runDefer;
}) (1) (1);
常数take=n=>codata=>{
常数go=([x,tx],acc,i)=>
i==n
?acc
:go(tx.runDefer,acc.concat(x),i+1);
返回go(codata,[],0);
};
console.log(

采取(10)(小谎))我将在数据构造函数本身中对thunk进行编码。例如,考虑.</P>
//whnf::Object->Object
常量whnf=obj=>{
for(对象项(obj)的常量[键,值]){
if(typeof val==“函数”&&val.length==0){
Object.defineProperty(对象、键、{
get:()=>Object.defineProperty(obj,key{
值:val()
})[关键]
});
}
}
返回obj;
};
//空::列表a
const empty=null;
//缺点:(a,列表a)->列表a
const cons=(head,tail)=>whnf({head,tail});
//fibs::List Int
常数fibs=cons(0,cons(1,()=>next(fibs,fibs.tail));
//下一步::(List Int,List Int)->List Int
const next=(xs,ys)=>cons(xs.head+ys.head,()=>next(xs.tail,ys.tail));
//假设::(Int,列表a)->列表a
常量take=(n,xs)=>n==0?空:cons(xs.head,()=>take(n-1,xs.tail));
//toArray::列表a->[a]
常量toArray=xs=>xs===空?[]:[xs.head,…toArray(xs.tail)];
// [0,1,1,2,3,5,8,13,21,34]

控制台日志(toArray(take(10,fibs))为什么不定义
const Defer=thunk=>thunk
并使用
()
而不是
?“你认为后者更可读吗?”帕特里克罗伯茨是的,我认为它更可读,并提供更多的“类型安全”来使用一个对象包装而不是裸露的thunk。出于同样的原因,我使用
app
而不是iLife。这是一个惊人的想法,一如既往。我想我更喜欢
tail
始终在WHNF中,这样我就可以直接在相应的构造函数中定义getter逻辑,例如
cons=(head,tail)=>({head,get tail(){return tail()}})
。这样就不需要对象内省,可以避免相关的陷阱,如
(…args)=>“我不是恶棍”
。缺点是我必须使用
cons
并始终使用thunk作为第二个参数。通过使用在第一次调用后替换自身的智能getter,我们还可以获得共享“效果”。WHNF是谜题中缺失的一块。再次感谢!第一类函数和在WHNF中创建表达式的能力是一种语言非常适合函数范式的主要因素。使用对象getter,我们可以在JS中表示值递归。下面是一个创建透明thunk的方法,这样我们就可以定义像“unfover”这样的惰性函数,它可以处理无限的列表。