Skip to content

Commit 0fa4f0b

Browse files
authored
Rollup merge of #86415 - Kmeakin:iterator-associativity-docs, r=dtolnay
Document associativity of iterator folds. Document the associativity of `Iterator::fold` and `DoubleEndedIterator::rfold` and add examples demonstrating this. Add links to direct users to the fold of the opposite associativity.
2 parents 469329d + 8eb0c0d commit 0fa4f0b

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

Diff for: library/core/src/iter/traits/double_ended.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,11 @@ pub trait DoubleEndedIterator: Iterator {
248248
/// Folding is useful whenever you have a collection of something, and want
249249
/// to produce a single value from it.
250250
///
251+
/// Note: `rfold()` combines elements in a *right-associative* fashion. For associative
252+
/// operators like `+`, the order the elements are combined in is not important, but for non-associative
253+
/// operators like `-` the order will affect the final result.
254+
/// For a *left-associative* version of `rfold()`, see [`Iterator::fold()`].
255+
///
251256
/// # Examples
252257
///
253258
/// Basic usage:
@@ -262,7 +267,8 @@ pub trait DoubleEndedIterator: Iterator {
262267
/// assert_eq!(sum, 6);
263268
/// ```
264269
///
265-
/// This example builds a string, starting with an initial value
270+
/// This example demonstrates the right-associative nature of `rfold()`:
271+
/// it builds a string, starting with an initial value
266272
/// and continuing with each element from the back until the front:
267273
///
268274
/// ```
@@ -276,6 +282,7 @@ pub trait DoubleEndedIterator: Iterator {
276282
///
277283
/// assert_eq!(result, "(1 + (2 + (3 + (4 + (5 + 0)))))");
278284
/// ```
285+
#[doc(alias = "foldr")]
279286
#[inline]
280287
#[stable(feature = "iter_rfold", since = "1.27.0")]
281288
fn rfold<B, F>(mut self, init: B, mut f: F) -> B

Diff for: library/core/src/iter/traits/iterator.rs

+21-1
Original file line numberDiff line numberDiff line change
@@ -2083,6 +2083,11 @@ pub trait Iterator {
20832083
/// Note: [`reduce()`] can be used to use the first element as the initial
20842084
/// value, if the accumulator type and item type is the same.
20852085
///
2086+
/// Note: `fold()` combines elements in a *left-associative* fashion. For associative
2087+
/// operators like `+`, the order the elements are combined in is not important, but for non-associative
2088+
/// operators like `-` the order will affect the final result.
2089+
/// For a *right-associative* version of `fold()`, see [`DoubleEndedIterator::rfold()`].
2090+
///
20862091
/// # Note to Implementors
20872092
///
20882093
/// Several of the other (forward) methods have default implementations in
@@ -2116,6 +2121,21 @@ pub trait Iterator {
21162121
///
21172122
/// And so, our final result, `6`.
21182123
///
2124+
/// This example demonstrates the left-associative nature of `fold()`:
2125+
/// it builds a string, starting with an initial value
2126+
/// and continuing with each element from the front until the back:
2127+
///
2128+
/// ```
2129+
/// let numbers = [1, 2, 3, 4, 5];
2130+
///
2131+
/// let zero = "0".to_string();
2132+
///
2133+
/// let result = numbers.iter().fold(zero, |acc, &x| {
2134+
/// format!("({} + {})", acc, x)
2135+
/// });
2136+
///
2137+
/// assert_eq!(result, "(((((0 + 1) + 2) + 3) + 4) + 5)");
2138+
/// ```
21192139
/// It's common for people who haven't used iterators a lot to
21202140
/// use a `for` loop with a list of things to build up a result. Those
21212141
/// can be turned into `fold()`s:
@@ -2140,7 +2160,7 @@ pub trait Iterator {
21402160
/// ```
21412161
///
21422162
/// [`reduce()`]: Iterator::reduce
2143-
#[doc(alias = "inject")]
2163+
#[doc(alias = "inject", alias = "foldl")]
21442164
#[inline]
21452165
#[stable(feature = "rust1", since = "1.0.0")]
21462166
fn fold<B, F>(mut self, init: B, mut f: F) -> B

0 commit comments

Comments
 (0)