I was lo开发者_StackOverflow社区oking at the way fold is defined for immutable.Set:
def fold [A1 >: A] (z: A1)(op: (A1, A1) ⇒ A1): A1
yet foldLeft is defined as:
def foldLeft [B] (z: B)(op: (B, A) ⇒ B): B
This looks weird for me, at least at first glance, since I was expecting fold to be able to change the type of the collection it returned, much like foldLeft does.
I imagine this is because foldLeft and foldRight guarantee something about the order in which the elements are folded. What is the guarantee given by fold?
When you're applying foldLeft
then your start value is combined with the first list element. The result is combined with the second list element. This result with the third and so on. Eventually, the list has collapsed to one element of the same type than your start value. Therefore you just need some type that can be combined by your function with a list element.
For foldRight
the same applies but in reverse order.
fold
does not guarantee the order in with the combinations are done. And it does not guarantee that it starts off at only one position. The folds might happen in parallel. Because you could have the parallelism it is required that any 2 list elements or return values can be combined – this adds a constraint to the types.
Regarding your comment that you have to see a case were order has an effect: Assume you're using folds to concatenate a list of characters and you want to have a text as result. If your input is A, B, C
, you probably would like to preserve the order to receive ABC
instead of ACB
(for example).
On the other hand if you're, say, just adding up numbers, the order does not matter. Summing up 1, 2, 3
gives 6
independent of the additions' order. In such cases using fold
instead of foldLeft
or foldRight
could lead to faster execution.
It seems that FoldLeft must return B. The method takes a B arg - this is an accumulator. Values of A are used to "add more to" a B. The final accumulated value is returned. I think FoldLeft and FoldRight are the same in this respect.
精彩评论