【发布时间】:2015-04-20 20:03:30
【问题描述】:
不久前,我在 StackOverflow 上发布了一个问题,显示 native implementation of reduceRight in JavaScript is annoying.因此,我创建了一个 Haskell 风格的 foldr 函数作为补救措施:
function foldr(array, callback, initial) {
var length = array.length;
if (arguments.length < 3) {
if (length > 0) var result = array[--length];
else throw new Error("Reduce of empty array with no initial value");
} else var result = initial;
while (length > 0) {
var index = --length;
result = callback(array[index], result, index, array);
}
return result;
}
但是,我从来没有使用过这个foldr 函数,因为我从来不需要从右到左遍历数组。这让我开始思考,为什么我不像在 Haskell 中那样在 JavaScript 中使用 foldr,在 JavaScript 中使用 foldr 的真实例子有哪些?
我可能是错的,但我相信 foldr 函数在 Haskell 中被广泛使用,因为:
- 懒惰评估 (foldl is tail recursive, so how come foldr runs faster than foldl?)
- 使用
foldr/build(Correctness of short cut fusion:foldr/build) 进行短切融合
这可以解释为什么 foldr 或 reduceRight 在 JavaScript 中没有被广泛使用。我还没有看到 foldr 在现实世界中仅用于从右到左的迭代顺序。
这让我想到了两个问题:
- 在 JavaScript 中使用
reduceRight的实际示例有哪些?也许你在 npm 包中使用过它。如果您能将我链接到您的代码并解释为什么需要使用reduceRight而不是reduce,那就太好了。 - 为什么
reduceRight没有像reduce在JavaScript 中那样广泛使用?我已经在这件事上提供了我的两分钱。我相信foldr主要只是因为它的惰性而使用,这就是为什么reduceRight在JavaScript 中不是很有用的原因。但是,我可能是错的。
对于第一个问题,我试图找到一些在 JavaScript 中使用 reduceRight 的真实示例。但是,我没有找到任何令人满意的答案。我发现的唯一例子是琐碎的和理论上的:
when to use reduce and reduceRight?
我正在寻找的是一个实际的例子。什么时候在 JavaScript 中使用 reduceRight 而不是 reduce 可行?
对于第二个问题,我知道这主要是基于意见,这就是为什么你不回答也没关系。这篇文章的主要焦点是第一个问题,而不是第二个。
【问题讨论】:
-
我不认为haskell中的
foldr函数是从右到左遍历的? -
@Sibi 你是对的。由于定义列表的方式(即
data [a] = [] | a : [a]),在 Haskell 中无法从右到左遍历列表。 Haskell 中的foldr函数只从右到左累积结果。但是,这个问题实际上与 Haskell 本身无关。 -
我从来没有在代码中使用过
reduceRight。我用过reduce至少一千次。 -
嗯,也许用它来实现某种
reverse? -
我最近对所有 cdn.js 脚本进行了代码调查。它发现 reduceRight 有 144 次使用,而 reduce 有 654 次使用。可悲的是,我扔掉了数据(花了 2 个小时来删除快速盒子上的所有脚本),否则我会找到你的细节,但如果 reduceRight 是使用的 1/4,它们应该在那里......
标签: javascript haskell iteration reduce fold