about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKarl Meakin <karlwfmeakin@gmail.com>2021-06-17 20:42:48 +0100
committerKarl Meakin <karlwfmeakin@gmail.com>2021-06-17 20:42:48 +0100
commit8eb0c0df0e8923a264d114291ab96e7bbfa13150 (patch)
treefcf78267246c7dc4601fba7ece616eda66476570
parent4d3ce2e7dac840d6ac7d658a5506eb31492fb3ef (diff)
downloadrust-8eb0c0df0e8923a264d114291ab96e7bbfa13150.tar.gz
rust-8eb0c0df0e8923a264d114291ab96e7bbfa13150.zip
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.
-rw-r--r--library/core/src/iter/traits/double_ended.rs9
-rw-r--r--library/core/src/iter/traits/iterator.rs22
2 files changed, 29 insertions, 2 deletions
diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs
index c302502b3b7..6d3ab788e5f 100644
--- a/library/core/src/iter/traits/double_ended.rs
+++ b/library/core/src/iter/traits/double_ended.rs
@@ -248,6 +248,11 @@ pub trait DoubleEndedIterator: Iterator {
     /// Folding is useful whenever you have a collection of something, and want
     /// to produce a single value from it.
     ///
+    /// Note: `rfold()` combines elements in a *right-associative* fashion. For associative
+    /// operators like `+`, the order the elements are combined in is not important, but for non-associative
+    /// operators like `-` the order will affect the final result.
+    /// For a *left-associative* version of `rfold()`, see [`Iterator::fold()`].
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -262,7 +267,8 @@ pub trait DoubleEndedIterator: Iterator {
     /// assert_eq!(sum, 6);
     /// ```
     ///
-    /// This example builds a string, starting with an initial value
+    /// This example demonstrates the right-associative nature of `rfold()`:
+    /// it builds a string, starting with an initial value
     /// and continuing with each element from the back until the front:
     ///
     /// ```
@@ -276,6 +282,7 @@ pub trait DoubleEndedIterator: Iterator {
     ///
     /// assert_eq!(result, "(1 + (2 + (3 + (4 + (5 + 0)))))");
     /// ```
+    #[doc(alias = "foldr")]
     #[inline]
     #[stable(feature = "iter_rfold", since = "1.27.0")]
     fn rfold<B, F>(mut self, init: B, mut f: F) -> B
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 78d317096b4..41d9993abaa 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -2083,6 +2083,11 @@ pub trait Iterator {
     /// Note: [`reduce()`] can be used to use the first element as the initial
     /// value, if the accumulator type and item type is the same.
     ///
+    /// Note: `fold()` combines elements in a *left-associative* fashion. For associative
+    /// operators like `+`, the order the elements are combined in is not important, but for non-associative
+    /// operators like `-` the order will affect the final result.
+    /// For a *right-associative* version of `fold()`, see [`DoubleEndedIterator::rfold()`].
+    ///
     /// # Note to Implementors
     ///
     /// Several of the other (forward) methods have default implementations in
@@ -2116,6 +2121,21 @@ pub trait Iterator {
     ///
     /// And so, our final result, `6`.
     ///
+    /// This example demonstrates the left-associative nature of `fold()`:
+    /// it builds a string, starting with an initial value
+    /// and continuing with each element from the front until the back:
+    ///
+    /// ```
+    /// let numbers = [1, 2, 3, 4, 5];
+    ///
+    /// let zero = "0".to_string();
+    ///
+    /// let result = numbers.iter().fold(zero, |acc, &x| {
+    ///     format!("({} + {})", acc, x)
+    /// });
+    ///
+    /// assert_eq!(result, "(((((0 + 1) + 2) + 3) + 4) + 5)");
+    /// ```
     /// It's common for people who haven't used iterators a lot to
     /// use a `for` loop with a list of things to build up a result. Those
     /// can be turned into `fold()`s:
@@ -2140,7 +2160,7 @@ pub trait Iterator {
     /// ```
     ///
     /// [`reduce()`]: Iterator::reduce
-    #[doc(alias = "inject")]
+    #[doc(alias = "inject", alias = "foldl")]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn fold<B, F>(mut self, init: B, mut f: F) -> B