-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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 and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Iterator::{sum_nonempty, product_nonempty} #50884
Conversation
This comment has been minimized.
This comment has been minimized.
1ab27ac
to
c1cb1ff
Compare
Invoking The way this should be done is through a separate iterator adaptor, like: pub struct IteratedCheck<I> {
iter: I,
iterated: bool,
}
impl<I: Iterator> Iterator for I {
type Item = <I as Iterator>::Item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iterated = true;
self.iter.next()
}
// forward other methods too
}
impl<T, U> Sum<U> for Option<T>
where
T: Sum<U>,
{
#[inline]
fn sum<I: Iterator<Item = U>>(iter: I) -> Option<T> {
let mut adapter = IteratedCheck { iter, iterated: false };
Some(adapter.by_ref().sum()).filter(adapter.iterated)
}
}
// and product too This allows you to avoid any performance burdens from |
src/libcore/iter/traits.rs
Outdated
@@ -836,6 +837,52 @@ macro_rules! float_sum_product { | |||
integer_sum_product! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize } | |||
float_sum_product! { f32 f64 } | |||
|
|||
#[stable(feature = "iter_arith_traits_option", since="1.29.0")] |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heh, just planning ahead. I'm sure the decision process will delay this at least 4 weeks given that it's insta-stable.
highfive failed to assign anybody again cc @rust-lang/infra. r? @sfackler |
Ping from triage @sfackler! This PR needs your review. |
This seemed a bit weird to me at first, but I think seems reasonable. @rfcbot fcp merge |
Team member @sfackler has proposed to merge this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
As I stated in my comment above, this should use an iterator adapter instead of using |
For completeness' sake I should mention that there is also an implementation of To get the same behaviour with Options, users could convert to Result: or we impl the
@clarcharr |
Yeah, the implementation is separate from the impl itself. |
☔ The latest upstream changes (presumably #50941) made this pull request unmergeable. Please resolve the merge conflicts. |
Similarly to the analogy to Edit: Not that the impl itself would directly conflict, but that it would imply a Sum that I don't think could coexist with this one.
|
(clarification from irc: scottmcm is asking about a potential impl such that one could It doesn't allow different types |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
I want to reiterate what @Emerentius said above:
I think that, with both Concretely, I propose taking the impls from here and putting them in a new |
I agree with choosing another method on |
I'm not in love with it, but Itertools does make use of it: |
Ping from triage @sfackler @Emerentius! How should we move forward with this PR? |
Sorry, I forgot about this PR for a while. I'll add the @clarcharr The advantage of Edit: Below is the original, wrong text of this post I forgot that Sum it's supposed to be generic over a different type than the output type.
Thinking about it again, I don't see why `Sum for Option` and `Sum> for Option` couldn't co-exist. It would simply mean that an `Iterator>` could sum into either `Option` or `Option>`.
Awesome for type inference (not), but otherwise [perfectly legal](http://play.rust-lang.org/?gist=233188ff5da98fc4bc360b29a953d4f6&version=stable&mode=debug&edition=2015).
Summing into I believe having those two trait impls is much preferable to having a special method that still couldn't sum |
c1cb1ff
to
178f0dc
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
178f0dc
to
7f3d0ca
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
7f3d0ca
to
77a91a6
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
hmm.. I thought I just did add that |
77a91a6
to
fba4e1c
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
These return Option<T>. Some(result) if the iter is nonempty, None otherwise. Allows differentiation between empty iterators and iterators that reduce to neutral elements.
fba4e1c
to
87d5107
Compare
Thanks @Emerentius for the updates! I wonder if we can perhaps think of a different name other than |
@alexcrichton I can see that if you read the I've looked at how other languages distinguish these fold- and fold1-like operations and came upon this handy list from wikipedia: folds in various languages Almost all of them either don't have a fold1, avoid the naming issue entirely by overloading or use a synonym for fold (namely, reduce). The *1 suffixing has weak precedence (Haskell) and the rest aren't applicable. I'm afraid there is no concise, immediately obvious name for this kind of operation. Edit: nom also uses the fold1 terminology |
As does itertools. |
To make sure I understand, you're thinking we could add |
Either |
Do others from @rust-lang/libs have thoughts on this? I personally sort of feel like this functionality belongs in |
Hmm, definitely feels hard to argue that core should have |
Ping from triage, @sfackler, @alexcrichton & @Emerentius. What is the status of this PR? It looks like there's been an FCP but there are still some open questions. |
Ping from triage again, @sfackler, @alexcrichton & @Emerentius! |
Given that the reception is just lukewarm, it probably is best to put it in itertools for now. |
That sounds reasonable to me! @Emerentius shall we close this PR in that case? |
Opened rust-itertools/itertools#300. |
This implements
{Sum<U>, Product<U>} for Option<T>
such that it returnsNone
if the iter is empty.That allows one to distinguish between an empty iter and iters that sum/multiply to their neutral element.
There's an alternative way of summing into
Option<T>
, which doesn't require a neutral starting element and therefore noT: Sum / Product
bound. It works by taking the first element and then adding / multiplying the rest onto that, but it can't accomodate the case of different types such asIterator<Item = U> -> Option<T>
. This PR keeps in line with the rest of the trait impls and therefore does requireT: Sum<U>
.This impl is for a stable trait and would therefore be insta-stable if merged.