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: