foldr 可以用作 MapReduce 吗?

Can foldr be used as MapReduce?

我在想,当你执行 MapReduce 时,你正在转换你的数据列表,然后使用 reduce 函数对转换后的数据做任何你想做的事情。我想我可以用 foldr 做同样的事情。当做类似 foldr (filterfun . mapfun) [] 的事情时。我可以说 Haskell 的 foldr 与 mapreduce 相同吗?还是我遗漏了什么?

不完全是。正如 Alec 的评论所指出的,foldr 不允许对归约进行重新排序或并行化。例如,如果您有

foldr (+) 0 [1,2,3,4]

那就是

1 + (2 + (3 + 4))

foldr 的实现无法拆分容器并对每一半分别求和,因为您只是给它一个函数 a -> b -> b 和一个值 b。除了将它应用于元素和累加器之外,它不能对该函数做任何事情。

foldMap :: (Foldable f, Monoid m)
        => (a -> m) -> f a -> m

另一方面,非常 mapReduce。由于 Monoid 约束带有关联性声明,因此您可以编写一个 foldMap 来并行减少容器的前半部分和后半部分,然后将它们与 [=21= 混合在一起].


foldr(在Data.Foldable中)的默认实现实际上使用foldMap:

foldr c n xs = appEndo (foldMap (Endo . c) xs) n

也就是把每个元素变成一个函数;这些函数都是组合的(组合形成一个以 id 为标识的幺半群)并将结果应用于种子。但是,您不能对中间函数做任何有用的事情!