Skip to content
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 factor_iter() and iter() methods #91

Merged
merged 12 commits into from
Feb 10, 2024
Merged

Conversation

aj-bagwell
Copy link
Contributor

fixes #90

src/lib.rs Outdated
/// ```
// TODO(MSRV): doc(alias) was stabilized in Rust 1.48
// #[doc(alias = "transpose")]
pub fn factor_iter(self) -> impl Iterator<Item = Either<L::Item, R::Item>> {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wish there was a better return type here so that e.g. the result would be a DoubleEndedIterator if both sides were, but map returns types are ugly even when they are not ineffable.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah... it can mostly be spelled out like this:

Either<
    iter::Map<L::IntoIter, impl Fn(L::Item) -> Either<L::Item, R::Item>>,
    iter::Map<R::IntoIter, impl Fn(R::Item) -> Either<L::Item, R::Item>>,
>

... and that will be conditionally double-ended and such. Or we can add a bespoke iterator type with a cleaner type signature.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I updated the type signature to your suggestion. It is a bit icky to expose so much of the implementation in the type signature as it would require a semver bump to change it, but I can't see a better option.

I thought about adding a bespoke iterator, but I was reluctant to polute either's otherwise minimalist name space, and it was going to be a whole pile of boilerplate to forward all the methods to the correct side to pick up any optimisations (e.g. for count or last).

Copy link
Member

Choose a reason for hiding this comment

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

It's not a great sign when the type signature is much longer than the implementation. :)

That almost makes me want to scrap the idea, except maybe it is still valuable to have something that guides type inference to the same Item = Either<L::Item, R::Item>. If you write that map_either implementation on its own, the Left side has ambiguous R, and the Right has ambiguous L. But from a few experiments, it does seem like the compiler's type inference figures out how to unify those if you try to use it as an Iterator, where they must be the same.

src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
Copy link
Member

@cuviper cuviper left a comment

Choose a reason for hiding this comment

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

I'm still thinking about the factor_iter signature, but the others can be tweaked.

src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
src/iterator.rs Outdated
/// ```
// TODO(MSRV): doc(alias) was stabilized in Rust 1.48
// #[doc(alias = "transpose")]
pub fn factor_iter(self) -> IterEither<L::IntoIter, R::IntoIter>
Copy link
Member

Choose a reason for hiding this comment

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

I couldn't get the MSRV compiler to be happy with resolving that huge return type in the tests, so I added a new type for it. (I also moved the iterator stuff into a module for cleanliness.)

Let me know what you think! I'm also wondering if iter_either would be a better method name, or else should I rename the new type to something like FactoredIter? #bikeshed away...

Copy link
Member

Choose a reason for hiding this comment

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

I'm thinking now to keep the factor method name, but I also split it into factor_into_iter, factor_iter, and factor_iter_mut.

Still not sure about IterEither, but I do like that its pronunciation is kind of close to Iterator. :)

@cuviper
Copy link
Member

cuviper commented Jan 31, 2024

@aj-bagwell any thoughts after the changes I made?

aj-bagwell and others added 12 commits February 9, 2024 17:45
…Eiter<L,R>>

Added as a method as Iter is already implemented if both sides are
iterators of the same type of item.
Based on cuviper's review add a bit more detail to the factor_iter
return type so that it will implement more specific iterators (e.g.
DoubleEndedIterator) if both sides do.
Co-authored-by: Josh Stone <cuviper@gmail.com>
Co-authored-by: Josh Stone <cuviper@gmail.com>
Co-authored-by: Jack Wrenn <me@jswrenn.com>
@cuviper cuviper added this pull request to the merge queue Feb 10, 2024
Merged via the queue into rayon-rs:main with commit 254fbf6 Feb 10, 2024
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add more Iterator helper methods
3 participants