在Javascript中,有一个reduce函数,它接受函数和数组,映射数组并返回函数返回的任何内容。
例如:
[1, 2, 3].reduce(function(acc, x) {
acc += x
return acc;
}, 0); // 6
在 Haskell 中,有折叠对我来说也有同样的作用:
foldl (+) 0 [1,2,3] -> 6
如果我想创建这种函数作为库,可以安全地将其称为“fold”而不是“reduce”,两者之间有什么区别吗?
除了名称之外,两者功能相同还是有一些差异
我用不同的语言进行演示,因为Js没有foldl功能。
谢谢
命名不一致,并且取决于语言。
在 Kotlin 等某些环境中,
reduce
不采用初始值,但 fold
则采用初始值。在 Haskell 中,有 foldl
和 foldl1
来区分这两种类型。在 Clojure 中,同一个函数 reduce
对于获取初始值或不获取初始值有不同的重载。
它们基本上描述了相同的概念,我从未发现这两个名称之间有任何明显的区别。
另一个角度是:
reduce
返回标量值,而fold
返回函数:
function dyadic(x, y) {
return x + y;
};
initialValue = 0;
a_list = [1, 2, 3];
// --------- REDUCE -----------------------------
// reduce returns a scalar value:
console.log(a_list.reduce(dyadic, initialValue));
// --------- FOLD -------------------------------
// fold returns a polyadic function:
function fold(d_func, initialValue) {
return function (...list) {
return list.reduce(d_func, initialValue);
};
};
// using fold to build the polyadic function build_sum:
build_sum = fold(dyadic, initialValue);
// finally obtain the scalar value by calling built function:
console.log(build_sum(...a_list));
// or using arrow notation:
dyadic2 = (x, y) => x + y;
fold2 = (d_func, initialValue) => (...list) => list.reduce(d_func, initialValue);
build_sum2 = fold2(dyadic2, initialValue);
console.log(build_sum2(...a_list));