add Option::{zip,zip_with} methods under "option_zip" gate by WaffleLapkin · Pull Request #69997 · rust-lang/rust (original) (raw)

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Conversation21 Commits3 Checks0 Files changed

Conversation

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters

[ Show hidden characters]({{ revealButtonHref }})

WaffleLapkin

Edit: Tracking issue


This PR introduces 2 methods - Option::zip and Option::zip_with with
respective signatures:

I'm not sure about the name "zip", maybe we can find a better name for this.
(I would prefer union for example, but this is a keyword :( )


Recently in a russian rust begginers telegram chat a newbie asked (translated):

Are there any methods for these conversions:

  1. (Option<A>, Option<B>) -> Option<(A, B)>
  2. Vec<Option<T>> -> Option<Vec<T>>

?

While second (2.) is clearly vec.into_iter().collect::<Option<Vec<_>>(), the
first one isn't that clear.

I couldn't find anything similar in the core and I've come to this solution:

let tuple: (Option, Option) = ...; let res: Option<(A, B)> = tuple.0.and_then(|a| tuple.1.map(|b| (a, b)));

However this solution isn't "nice" (same for just match/if let), so I thought
that this functionality should be in core.

@rust-highfive

r? @LukasKalbertodt

(rust_highfive has picked a reviewer for you, use r? to override)

@Centril

I'm not sure about the name "zip", maybe we can find a better name for this.

zip is clearly the right name as it is analogous to Iterator::zip. (We don't have Iterator::zip_with though.)

@WaffleLapkin

Other currently possible solutions:

let tuple: (Option, Option) = ...; let res: Option<(A, B)> = match tuple { (Some(a), Some(b)) => Some((a, b)), _ => None, };

#![feature(try_blocks)] // require nightly let tuple: (Option, Option) = ...; let res: Option<(A, B)> = try { (tuple.0?, tuple.1?) }

(playground)

@WaffleLapkin

We don't have Iterator::zip_with though

Hmmm, a.zip_with(b, |x, y| ...) is the same as a.zip(b).map(|(x, y)| ...)

@Centril

I'm in favor of adding Option::zip at least by analogy to Iterator::zip (see also Option::flatten which was also accepted by analogy to Iterator::flatten). Also, I believe Option::zip to be a useful and fairly common operation to justify its addition on its own merits (as opposed to a precedent based justification).

I'm less sure about zip_with though, as it does not have similar precedent.

@bors

☔ The latest upstream changes (presumably #70062) made this pull request unmergeable. Please resolve the merge conflicts.

LukasKalbertodt

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a bunch for the PR!

I agree with @Centril and am also in favor of adding Option::zip. I think I'd prefer not to add Option::zip_with though. I think it's pretty niche. But I'm fine with merging it as unstable to find out if users find good uses for it.

I added a few line comments, but nothing serious. And you need to rebase.

@WaffleLapkin

This commit introduces 2 methods - Option::zip and Option::zip_with with respective signatures:

I'm not sure about the name "zip", maybe we can find a better name for this. (I would prefer union for example, but this is a keyword :( )


Recently in a russian rust begginers telegram chat a newbie asked (translated):

Are there any methods for these conversions:

  1. (Option<A>, Option<B>) -> Option<(A, B)>
  2. Vec<Option<T>> -> Option<Vec<T>>

?

While second (2.) is clearly vec.into_iter().collect::<Option<Vec<_>>(), the first one isn't that clear.

I couldn't find anything similar in the core and I've come to this solution:

let tuple: (Option<A>, Option<B>) = ...;
let res: Option<(A, B)> = tuple.0.and_then(|a| tuple.1.map(|b| (a, b)));

However this solution isn't "nice" (same for just match/if let), so I thought that this functionality should be in core.

@WaffleLapkin

If Option::zip_with addition is so questionable, shouldn't we use a different gate for it ("option_zip_with")?

@WaffleLapkin

@LukasKalbertodt

If Option::zip_with addition is so questionable, shouldn't we use a different gate for it ("option_zip_with")?

I don't have a strong preference, but I'd say you can keep it as is for now. I suspect that when we are discussing stabilizing zip, we will either also stabilize zip_with or remove it completely. I doubt we would be keeping it as unstable.

LukasKalbertodt

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a tiny thing still.

@WaffleLapkin

@LukasKalbertodt

@bors

📌 Commit 121bffc has been approved by LukasKalbertodt

@bors bors added S-waiting-on-bors

Status: Waiting on bors to run and complete tests. Bors will change the label on completion.

and removed S-waiting-on-review

Status: Awaiting review from the assignee but also interested parties.

labels

Mar 20, 2020

Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request

Mar 21, 2020

@Dylan-DPC

…bertodt

add Option::{zip,zip_with} methods under "option_zip" gate

This PR introduces 2 methods - Option::zip and Option::zip_with with respective signatures:

I'm not sure about the name "zip", maybe we can find a better name for this. (I would prefer union for example, but this is a keyword :( )


Recently in a russian rust begginers telegram chat a newbie asked (translated):

Are there any methods for these conversions:

  1. (Option<A>, Option<B>) -> Option<(A, B)>
  2. Vec<Option<T>> -> Option<Vec<T>>

?

While second (2.) is clearly vec.into_iter().collect::<Option<Vec<_>>(), the first one isn't that clear.

I couldn't find anything similar in the core and I've come to this solution:

let tuple: (Option<A>, Option<B>) = ...;
let res: Option<(A, B)> = tuple.0.and_then(|a| tuple.1.map(|b| (a, b)));

However this solution isn't "nice" (same for just match/if let), so I thought that this functionality should be in core.

Centril added a commit to Centril/rust that referenced this pull request

Mar 21, 2020

@Centril

…bertodt

add Option::{zip,zip_with} methods under "option_zip" gate

This PR introduces 2 methods - Option::zip and Option::zip_with with respective signatures:

I'm not sure about the name "zip", maybe we can find a better name for this. (I would prefer union for example, but this is a keyword :( )


Recently in a russian rust begginers telegram chat a newbie asked (translated):

Are there any methods for these conversions:

  1. (Option<A>, Option<B>) -> Option<(A, B)>
  2. Vec<Option<T>> -> Option<Vec<T>>

?

While second (2.) is clearly vec.into_iter().collect::<Option<Vec<_>>(), the first one isn't that clear.

I couldn't find anything similar in the core and I've come to this solution:

let tuple: (Option<A>, Option<B>) = ...;
let res: Option<(A, B)> = tuple.0.and_then(|a| tuple.1.map(|b| (a, b)));

However this solution isn't "nice" (same for just match/if let), so I thought that this functionality should be in core.

bors added a commit to rust-lang-ci/rust that referenced this pull request

Mar 21, 2020

@bors

Labels

S-waiting-on-bors

Status: Waiting on bors to run and complete tests. Bors will change the label on completion.