rustoption-type

Is there any built in way to map over a pair of Options (apply a function when both are Some)?


In the following sample program, is there any way I could avoid having to define map2?

fn map2<T, U, V, F: Fn(T, U) -> V>(f: F, a: Option<T>, b: Option<U>) -> Option<V> {
    match a {
        Some(x) => match b {
            Some(y) => Some(f(x, y)),
            None => None,
        },
        None => None,
    }
}

fn main() {
    let a = Some(5);
    let b = Some(10);
    let f = |a, b| {
        a + b
    };
    let res = map2(f, a, b);
    println!("{:?}", res);
    // prints Some(15)
}

For people who also speak Haskell, I guess this question could also be phrased as "Is there any tool we can use instead of liftM2 in Rust?"


Solution

  • I don't believe there's a direct function equivalent to liftM2, but you can combine Option::and_then and Option::map like this:

    fn main() {
        let a = Some(5);
        let b = Some(10);
        let f = |a, b| {
            a + b
        };
    
        println!("{:?}", a.and_then(|a| b.map(|b| f(a, b))));
    }
    

    Output:

    Some(15)