Javascript 没有';它不会崩溃,并且工作得相当好

Javascript 没有';它不会崩溃,并且工作得相当好,javascript,reduce,fold,Javascript,Reduce,Fold,我想要一个类似于Haskell或lisp中的foldr的foldr。My foldr在大型阵列上导致堆栈溢出,可能是因为堆栈上的大量挂起操作在到达基本情况之前无法减少。您将如何优化我的foldr,使其在大型阵列中正常工作 constfoldr=(f,acc,[x,…xs])=> (x的类型===‘未定义’) ? 行政协调会 :f(x,foldr(f,acc,xs)) foldr((x,acc)=>x+acc,0,[…数组(100000).keys()) foldr几乎是: const flip=

我想要一个类似于Haskell或lisp中的foldr的foldr。My foldr在大型阵列上导致堆栈溢出,可能是因为堆栈上的大量挂起操作在到达基本情况之前无法减少。您将如何优化我的foldr,使其在大型阵列中正常工作

constfoldr=(f,acc,[x,…xs])=>
(x的类型===‘未定义’)
? 行政协调会
:f(x,foldr(f,acc,xs))
foldr((x,acc)=>x+acc,0,[…数组(100000).keys())

foldr
几乎是:

const flip=f=>(a,b)=>f(b,a)
常数foldr=(f、acc、arr)=>
右后减速器(翻转(f),附件)
如果希望保留对解包提供给您的任意iterables的支持,请将
arr.reduceRight
替换为
[…arr].reduceRight

const flip=f=>(a,b)=>f(b,a)
常数foldr=(f、acc、arr)=>
右后减速器(翻转(f),附件)

log(foldr((x,acc)=>x+acc,0,[…数组(100000).keys()))
foldr
几乎是:

const flip=f=>(a,b)=>f(b,a)
常数foldr=(f、acc、arr)=>
右后减速器(翻转(f),附件)
如果希望保留对解包提供给您的任意iterables的支持,请将
arr.reduceRight
替换为
[…arr].reduceRight

const flip=f=>(a,b)=>f(b,a)
常数foldr=(f、acc、arr)=>
右后减速器(翻转(f),附件)

log(foldr((x,acc)=>x+acc,0,[…Array(100000).keys()]))
问题是JavaScript使用的默认类似列表的结构是可变数组(不是真正的类似c的数组,它们可能在内部实现为树),而Haskell或Lisp等函数式语言使用链表。您可以在固定时间内获得链表的第一个元素和其余元素,而不会发生变异。如果您想在JavaScript中执行相同的操作(不进行变异),则必须创建(分配)新数组以获取数组的其余部分

然而,整个foldr可以通过内部突变实现。整个函数不会进行任何外部变异:

const foldr = (f, initialValue, arr) => {
  let value = initialValue;

  for (let i = arr.length - 1; i >= 0; i--) {
    value = f(arr[i], value)
  }

  return value;
}

问题在于JavaScript使用的默认类似列表的结构是可变数组(不是真正的类似c的数组,它们可能在内部实现为树),而Haskell或Lisp等函数式语言使用链表。您可以在固定时间内获得链表的第一个元素和其余元素,而不会发生变异。如果您想在JavaScript中执行相同的操作(不进行变异),则必须创建(分配)新数组以获取数组的其余部分

然而,整个foldr可以通过内部突变实现。整个函数不会进行任何外部变异:

const foldr = (f, initialValue, arr) => {
  let value = initialValue;

  for (let i = arr.length - 1; i >= 0; i--) {
    value = f(arr[i], value)
  }

  return value;
}