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

Handling unknown/arbitrary sized list of generics. #7488

Closed
cglacet opened this issue Feb 20, 2019 · 3 comments
Closed

Handling unknown/arbitrary sized list of generics. #7488

cglacet opened this issue Feb 20, 2019 · 3 comments

Comments

@cglacet
Copy link

cglacet commented Feb 20, 2019

Proposal

Adding a way to handle lists of generics with unbounded size:

function identity<...T>(array: T) {
  // ...
}

Which would be equivalent to:

declare function identity2<A, B>(items:[A, B]): [A, B];
declare function identity2<A, B, C>(items:[A, B, C]): [A, B, C];
// with infinitely many signatures
function identity<T>(items:T): T {
	return items;
} 

Test it here.

Use case

That would for example be useful to type a reverse function. That function would take an arbitrary number of arguments and return them in reverse order: reverse(1, 2, "3") = ["3", 2, 1]. For now it seems that this is only possible by having a fixed length for the input, or by declaring several signatures, one for each possible number of arguments.

A more concrete use case I have is with this zip function, which for now only takes 2, 3 or 4 iterables as parameter:

declare function zip<A, B>(Iterable<A>, Iterable<B>): Iterable<[A, B]>;
declare function zip<A, B, C>(Iterable<A>, Iterable<B>, Iterable<C>): Iterable<[A, B, C]>;
declare function zip<A, B, C, D>(Iterable<A>, Iterable<B>, Iterable<C>, Iterable<D>): Iterable<[A, B, C, D]>;
export function *zip<T>(...iterables:Array<Iterable<T>>): Iterable<Array<T>> {
   const iterators = iterables.map(iterable => iter(iterable));
   while(true){
      const items = iterators.map(iterator => iterator.next());
      if (items.some(item => item.done)){
         return;
      }
      yield ((items.map(item => { return item.value }): Array<any>): Array<T>);
  }
}
@jbrown215
Copy link
Contributor

Is this sufficient for your use case?

@cglacet
Copy link
Author

cglacet commented Feb 25, 2019

Well, I think it is!

export function *iter<T>(iterable:Iterable<T>): Iterator<T> {
   yield* iterable;
}

export function *zip<T: $ReadOnlyArray<mixed>>(...iterables:Array<Iterable<T>>): Iterable<Array<T>> {
   const iterators = iterables.map(iterable => iter(iterable));
   while(true){
      const items = iterators.map(iterator => iterator.next());
      if (items.some(item => item.done)){
         return;
      }
      yield ((items.map(item => { return item.value }): Array<any>): Array<T>);
  }
}

@SamChou19815
Copy link
Contributor

SamChou19815 commented Jun 27, 2023

Duplicate of #1251

@SamChou19815 SamChou19815 closed this as not planned Won't fix, can't repro, duplicate, stale Jun 27, 2023
@SamChou19815 SamChou19815 marked this as a duplicate of #1251 Jun 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants