-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
impl FromIterator<()> for () #45379
impl FromIterator<()> for () #45379
Conversation
This just collapses all unit items from an iterator into one. This is more useful when combined with higher-level abstractions, like collecting to a `Result<(), E>` where you only care about errors: ```rust use std::io::*; data = vec![1, 2, 3, 4, 5]; let res: Result<()> = data.iter() .map(|x| writeln!(stdout(), "{}", x)) .collect(); assert!(res.is_ok()); ```
(rust_highfive has picked a reviewer for you, use r? to override) |
I also thought about letting this consume any |
This is related to #44546 too, whether or not it might take any |
@rfcbot fcp merge Seems like a nifty idea to me! |
Team member @alexcrichton has proposed to merge this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once these reviewers reach consensus, 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. |
I consider this an antipattern. I mean we have fn for_each<F, R, R2>(self, f: F) -> R where
Self: Sized,
F: FnMut(Self::Item) -> R2,
R: FromIterator<R2>,
{
self.map(f).collect()
} Both changes together I can get behind. But it feels inconsistent if we consider code idiomatic that does |
@oli-obk On it's own, I would agree this is pretty useless, and I would encourage using
I would not encourage |
This feels like a If we had |
let res: Result<()> = data.iter()
.try_fold((), |(),x| writeln!(stdout(), "{}", x)); |
|
I'm not sure what you're referring to. There's a blanket impl of |
@scottmcm Have you proposed |
@cuviper I'm working on it 😄 (Got ahead of myself and broke something bad enough that the tests won't tell me what, though, so I need to split it up into some simpler changes. But I'm not in too much of a rush, because it'll only be full goodness once #45225 fixes #43278.) |
Nice, that's very thorough! |
Well, the Looking at cuviper's example again, that's of course the same pattern as fn try_for_each<F, R>(&mut self, mut f: F)
where Self: Sized, F: FnMut(Self::Item) -> R, R: Try<Ok=()>
{
self.try_fold((), move |(), x| f(x))
} (With, like Edit: That pattern ( |
@scottmcm you're shaving away all the motivation here... and that's OK! 😄 Are there any other higher-level abstractions that would still be useful with this |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
So at this point the libs team have all signed off on merging this, but @cuviper just to confirm, you're still ok with merging this? |
I'm still OK with this. I like the generality of the |
Ok! @bors: r+ |
📌 Commit 68d05b2 has been approved by |
impl FromIterator<()> for () This just collapses all unit items from an iterator into one. This is more useful when combined with higher-level abstractions, like collecting to a `Result<(), E>` where you only care about errors: ```rust use std::io::*; data = vec![1, 2, 3, 4, 5]; let res: Result<()> = data.iter() .map(|x| writeln!(stdout(), "{}", x)) .collect(); assert!(res.is_ok()); ```
☀️ Test successful - status-appveyor, status-travis |
Short-circuiting internal iteration with Iterator::try_fold & try_rfold These are the core methods in terms of which the other methods (`fold`, `all`, `any`, `find`, `position`, `nth`, ...) can be implemented, allowing Iterator implementors to get the full goodness of internal iteration by only overriding one method (per direction). Based off the `Try` trait, so works with both `Result` and `Option` (:tada: #42526). The `try_fold` rustdoc examples use `Option` and the `try_rfold` ones use `Result`. AKA continuing in the vein of PRs #44682 & #44856 for more of `Iterator`. New bench following the pattern from the latter of those: ``` test iter::bench_take_while_chain_ref_sum ... bench: 1,130,843 ns/iter (+/- 25,110) test iter::bench_take_while_chain_sum ... bench: 362,530 ns/iter (+/- 391) ``` I also ran the benches without the `fold` & `rfold` overrides to test their new default impls, with basically no change. I left them there, though, to take advantage of existing overrides and because `AlwaysOk` has some sub-optimality due to #43278 (which 45225 should fix). If you're wondering why there are three type parameters, see issue #45462 Thanks for @bluss for the [original IRLO thread](https://internals.rust-lang.org/t/pre-rfc-fold-ok-is-composable-internal-iteration/4434) and the rfold PR and to @cuviper for adding so many folds, [encouraging me](#45379 (comment)) to make this PR, and finding a catastrophic bug in a pre-review.
497: impl FromParallelIterator<()> for () r=cuviper a=cuviper This is more useful when combined with higher-level abstractions, like collecting to a `Result<(), E>` where you only care about errors. This is a parallel version of rust-lang/rust#45379. Cc #496 498: FromParallelIterator and ParallelExtend Cow for String r=cuviper a=cuviper Parallel version of rust-lang/rust#41449.
497: impl FromParallelIterator<()> for () r=cuviper a=cuviper This is more useful when combined with higher-level abstractions, like collecting to a `Result<(), E>` where you only care about errors. This is a parallel version of rust-lang/rust#45379. Cc #496
497: impl FromParallelIterator<()> for () r=cuviper a=cuviper This is more useful when combined with higher-level abstractions, like collecting to a `Result<(), E>` where you only care about errors. This is a parallel version of rust-lang/rust#45379. Cc #496
Add Iterator::try_for_each The fallible version of `for_each` aka the stateless version of `try_fold`. Inspired by @cuviper's comment in rust-lang#45379 (comment) as a more direct and obvious solution than `.map(f).collect::<Result<(), _>>()`. Like `for_each`, no need for an `r` version thanks to overrides in `Rev`. `iterator_try_fold` tracking issue: rust-lang#45594
Add Iterator::try_for_each The fallible version of `for_each` aka the stateless version of `try_fold`. Inspired by @cuviper's comment in rust-lang#45379 (comment) as a more direct and obvious solution than `.map(f).collect::<Result<(), _>>()`. Like `for_each`, no need for an `r` version thanks to overrides in `Rev`. `iterator_try_fold` tracking issue: rust-lang#45594
This just collapses all unit items from an iterator into one. This is
more useful when combined with higher-level abstractions, like
collecting to a
Result<(), E>
where you only care about errors: