Fold with closure that returns Result and early-out


#1

Hey all, I have a classic example of wanting to use fold – say I have a method like

A::foo(&self, x: T) -> A

and I have an A, and a Vec<T>. I want to essentially call a.foo(t1).foo(t2).foo(t3) with those t* variables coming from the Vec<T> – a very easy thing to do with a simple ts.iter().fold(a, |a, t| a.foo(t)).

However, that’s not all. Let’s say foo actually returns Result<A, Error> instead of just A. So I actually want my closure to be able to return a Result, and now I want some version of fold which handles these Result types and early-out at the first instance of an Err being returned. That is, fn fold_with_results<B, F, E>(self, init: B, f: F) -> Result<B, E> where F: FnMut(B, Self::Item) -> Result<B, E>

I’ve run into this a surprising number of times already, and I can’t find an easy solution, so I end up using more verbose for loops.

So is there some trick in std that lets me do something like this? If not, does anyone know of a crate that has such a utility function? (I have found fallible_iterator but its version of fold doesn’t seem to handle this either).


#2

Maybe https://docs.rs/itertools/0.5.9/itertools/trait.Itertools.html#method.fold_while or https://docs.rs/itertools/0.5.9/itertools/trait.Itertools.html#method.fold_results?


#3

@jethrogb d’oh, of course I should have (re)checked itertools. I thought I had done so but it’d apparently been too long for me to remember :slight_smile: thanks for the pointer.


#4

Hmm, actually it seems fold_results isn’t quite what I want… it’s about running an (B, A) -> B closure over an Iter<Item=Result<A, E>> to get a Result<B, E>. I have an Iter of regular old items but the closure wants to return the Result.

fold_while definitely looks like a building block for creating what I want, but isn’t directly there. I guess I’m just way overestimating the need for the kind of thing I’m looking for :slight_smile:


#5

Not entirely…


#6

Nice! That is exactly what I’m looking for :slight_smile: Glad to see it’s getting some attention. I also really like that it’s going into a more general direction than just Result, getting slightly closer to the foldM I know and love :slight_smile: