Reputation: 2395
I was thinking that when you do a MapReduce you are transforming your datalist and then using a reduce function to do whatever you want with the transformed data. I guess I can do the same with foldr
. When doing something like foldr (filterfun . mapfun) []
. Can I say that Haskell's foldr is identical to a mapreduce? Or am I missing something?
Upvotes: 0
Views: 275
Reputation: 48580
Not quite. As Alec's comment indicates, foldr
doesn't allow reduction to be reordered or parallelized. For example, if you have
foldr (+) 0 [1,2,3,4]
then that's
1 + (2 + (3 + 4))
The implementation of foldr
can't split the container and sum each half separately, because you're just giving it a function a -> b -> b
and a value b
. It can't do anything with the function except apply it to both an element and an accumulator.
foldMap :: (Foldable f, Monoid m)
=> (a -> m) -> f a -> m
on the other hand, is very much a mapReduce
. Since the Monoid
constraint carries with it a claim of associativity, you can write a foldMap
that reduces the first half of the container and the second half in parallel, and then mashes them together with <>
.
The default implementation of foldr
(in Data.Foldable
) actually uses foldMap
:
foldr c n xs = appEndo (foldMap (Endo . c) xs) n
That is, it turns each element into a function; those functions are all composed (composition forms a monoid with id
as its identity) and the result applied to the seed. You can't, however, do anything useful with the intermediate functions!
Upvotes: 8