JavaScript中reduceRight的本机实现是错误的

JavaScript中reduceRight的本机实现是错误的,javascript,reduce,fold,associativity,commutativity,Javascript,Reduce,Fold,Associativity,Commutativity,对于数组a元素上的关联操作f,以下关系应成立:a.reduce(f)应等同于a.reduceRight(f) 事实上,它确实适用于既关联又可交换的操作。对于 例如: const a=[0,1,2,3,4,5,6,7,8,9]; 常数加=(a,b)=>a+b; console.log(a.reduce(add)); console.log(a.reduceRight(add)) 像我这样实现reduceRight真的更有意义吗 也许吧。但是,JavaScript数组迭代器并非来自纯函数式编程背景

对于数组
a
元素上的关联操作
f
,以下关系应成立:
a.reduce(f)
应等同于
a.reduceRight(f)

事实上,它确实适用于既关联又可交换的操作。对于 例如:

const a=[0,1,2,3,4,5,6,7,8,9];
常数加=(a,b)=>a+b;
console.log(a.reduce(add));
console.log(a.reduceRight(add))
像我这样实现
reduceRight
真的更有意义吗

也许吧。但是,JavaScript数组迭代器并非来自纯函数式编程背景

为什么原生的
reduceRight
没有像我那样实现

因为使用相同的参数顺序更简单(更容易记住),所以累加器总是第一个

数组上的基本操作是
reduce
,它总是从0迭代到n-1。只有在Haskell中,其递归构建的列表
foldr
才更有意义(具有
build
二元性,在无限列表上工作得很好…)。注意命名不是
reduce
+
reduceLeft

然后,
reduceRight
不会反转折叠操作,它只是反转迭代顺序。这也是文档和教程中通常解释的方式,例如在最终指南中:

reduceRight()
的工作原理与
reduce()
类似,只是它从最高层处理数组

另外,JS1.8中的
reduce
/
reduceRight
(请参阅)也采用了这种方法:它只是以结束为起点翻转,并对步长值求反

ES4规范的设计遵循了这一思路。它确实提到了Haskell,但整个文档根本没有处理
回调的参数顺序。可能在Haskell的不常见语法中丢失了不同的顺序,或者是规范的类型名称,因此两个签名都以
(a->b->…
)开头。更多的讨论深入到了

一些相关摘录:

[这种方法的]好处:

  • 就像Python=>Python社区分享一样
  • 折叠的完全通用性(左)
  • 但也要做一个简单的例子,其中第一个元素是基础 元素,更简单
我猜大多数人会发现从左到右版本的reduce more
直观,因为它们通常从左到右遍历数组。 另外,Python就是这么做的

我认为提供还原权也很重要,
因为不是每个操作都是关联的,有时人们需要 从右向左走

最后,这就是:

阵列附加功能:按照FF当前支持的方式对其进行规范


这不正是因为从不同的方向进行操作吗?这就是两者兼有的意义所在,非交换操作必然会返回不同的结果。@可能它们可以在不同的方向进行操作,但对于关联操作,它们应该返回相同的结果。例如:
foldl1(++)xs==foldr1(++)xs在Haskell中是
True