Add Iterator::{sum_nonempty, product_nonempty}#50884
Add Iterator::{sum_nonempty, product_nonempty}#50884Emerentius wants to merge 1 commit intorust-lang:masterfrom
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 tooThis allows you to avoid any performance burdens from |
src/libcore/iter/traits.rs
Outdated
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
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. DetailsThinking 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 returnsNoneif 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 / Productbound. 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.