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
为标识的幺半群)并将结果应用于种子。但是,您不能对中间函数做任何有用的事情!
我在想,当你执行 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
为标识的幺半群)并将结果应用于种子。但是,您不能对中间函数做任何有用的事情!