I sure would like to have the method Option::zip
fn zip<U>(self, Option<U>) -> Option<(T, U)>
Currently I have to do a.into_iter().zip(b).next() which is just a tiny bit verbose.
a.and_then(|x| b.map(|y| (x, y))) also works, although isn't much less verbose.
The desired behavior here is to return Some iff self and other are Some?
The signature looks like it should take self by value rather than by ref.
I think this is a pretty good idea since it's so simple, but I am not sure what the use-case is.
alternatively there could be an impl<T, U> Into<Option<(T, U)>> for (Option<T>, Option<U>). But that might be a bit too much logic for the into operation.
Option::zip(a, b)
vs
(a, b).into()
I think that second approach is better, but it type of (a, b).into() is not inferrable right now.
:-1: for me. It seems like a niche use case. Also, having an operation named zip on Iterator that acts slightly different seems unfortunate.
FWIW using #243 extended with Option compatibility, it would also be possible to express this as try { (a?, b?) }.
This is now implemented, although unstable.
Closing in favor of tracking issue: https://github.com/rust-lang/rust/issues/70086
Interesting idea. That鈥檚 basically a specialization of applicative functors. Indeed, you use a tuple constructor, but you could do much more with an applicative functor. It鈥檚 a pity we don鈥檛 have applicative functor notation in Rust. :)
As a base of comparison, you do it this way in Haskell:
-- all these are identical
x = liftA2 (,) firstMaybe secondMaybe
x = (,) <$> firstMaybe <*> secondMaybe
x = do
a <- firstMaybe
b <- secondMaybe
pure (a, b)
@phaazon note that we have special-cased do (I think?...) for some types, e.g.:
let x = try { (first?, second?) };
The try{} block itself is unstable (https://github.com/rust-lang/rust/issues/31436) but the question mark operator in functions is stable.
Most helpful comment
This is now implemented, although unstable.
Closing in favor of tracking issue: https://github.com/rust-lang/rust/issues/70086