Неловкое поведение при необходимости мутировать аккумулятор можно объяснить отсутствием ГХ.
Ничто не мешает Rust выполнять то, что вы просите.
Пример возможной реализации:
pub struct Mapscan<I, A, F> {
accu: Option<A>,
iter: I,
f: F,
}
impl<I, A, F> Mapscan<I, A, F> {
pub fn new(iter: I, accu: Option<A>, f: F) -> Self {
Self { iter, accu, f }
}
}
impl<I, A, F> Iterator for Mapscan<I, A, F>
where
I: Iterator,
F: FnMut(&A, I::Item) -> Option<A>,
{
type Item = A;
fn next(&mut self) -> Option<Self::Item> {
self.accu.take().map(|accu| {
self.accu = self.iter.next().and_then(|item| (self.f)(&accu, item));
accu
})
}
}
trait IterPlus: Iterator {
fn map_scan<A, F>(self, accu: Option<A>, f: F) -> Mapscan<Self, A, F>
where
Self: Sized,
F: FnMut(&A, Self::Item) -> Option<A>,
{
Mapscan::new(self, accu, f)
}
}
impl<T: ?Sized> IterPlus for T where T: Iterator {}
fn main() {
let xs = [1, 2, 3, 4, 5];
let vs = xs
.iter()
.map_scan(Some(0), |acc, x| Some(acc + x));
assert_eq!(vs.collect::<Vec<_>>(), [0, 1, 3, 6, 10, 15]);
}