Description
Proposal
Problem statement
Iterator::fold
is an extremely useful API to process all the elements in an iterator.
Sometimes you don't have a sensible initial value. This is where Iterator::reduce
comes in.
However, this removes some flexibility with the return type. It must be the same as the item stream.
There's a middle ground where you instead derive the initial fold value with the first element in the iterator.
Motivation, use-cases
The docs for fold
presents this example
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)");
There's no way to avoid the (0 + 1)
situation with either fold
or reduce
unless you fold over a Option<String>
or reduce over String
iterators.
With fold_first
, this is easy
let numbers = [1, 2, 3, 4, 5];
let result = numbers.iter().fold_first(
|first| first.to_string(),
|acc, &x| format!("({acc} + {x})"),
).unwrap();
assert_eq!(result, "((((1 + 2) + 3) + 4) + 5)");
Solution sketches
Links and related work
What happens now?
This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals in its weekly meeting. You should receive feedback within a week or two.