Adding `zip` (and potentially others) to `Result`

Hello,

Option's zip method is very useful. What do you think about adding the same method to Result. Here's an example of an implementation.

pub trait ResultExt<T, E> {
    fn zip<U>(self, other: Result<U, E>) -> Result<(T, U), E>;
}

impl<T, E> ResultExt<T, E> for Result<T, E> {

    fn zip<U>(self, other: Result<U, E>) -> Result<(T, U), E> {
        match (self, other) {
            (Ok(a), Ok(b)) => Ok((a, b)),
            (Err(e), _) => Err(e),
            (_, Err(e)) => Err(e),
        }
    }
}

I'm not sure that iteration really fits the concept Result is attempting to model, but this is mostly a feeling. If you only care about using your results as options though, they can be converted extremely tersely: result_a.ok().zip(result_b.ok()) works now.

Result already is iterable.

Your proposed solution does not allow for getting the Err easily.

We have most times in real cases Result<T1, E1> and Result<T2, E2> and zip for this case looks awful.

This could be written as try { (a?, b?) } if try blocks were stable.

4 Likes

The case where the errors are the same seems common enough.

It seems like an odd pattern for fallible operations that in the case both results are Err, then only the first error is returned. If you want only the first operation's error, then and_then may clarify the intention more.

2 Likes

Doesn't it have the same semantics as and_then?

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.