Как вы наберете 3 аргумента карри функции в машинопись - PullRequest
0 голосов
/ 15 ноября 2018

Или как вы определяете несколько подписей для возвращаемой функции

Я пытаюсь создать функцию с карри, но у меня возникают проблемы с перегрузками определения.В частности, если вы вызываете parallelMap с одним аргументом, вы можете вызвать следующий аргумент с 1 или 2 аргументами.Однако def помечен как недействительный.

[ts] Сигнатура перегрузки не совместима с реализацией функции.[2394]

export function parallelMap<T, R> (concurrency: number): (func: (data: T) => R | Promise<R>) => (iterable: AnyIterable<T>) => AsyncIterableIterator<R>

Полная реализация;

export function parallelMap<T, R> (concurrency: number): (func: (data: T) => R | Promise<R>, iterable: AnyIterable<T>) => AsyncIterableIterator<R>
export function parallelMap<T, R> (concurrency: number): (func: (data: T) => R | Promise<R>) => (iterable: AnyIterable<T>) => AsyncIterableIterator<R>
export function parallelMap<T, R> (concurrency: number, func: (data: T) => R | Promise<R>): (iterable: AnyIterable<T>) => AsyncIterableIterator<R>
export function parallelMap<T, R> (concurrency: number, func: (data: T) => R | Promise<R>, iterable: AnyIterable<T>): AsyncIterableIterator<R>
export function parallelMap<T, R> (
  concurrency: number,
  func?: (data: T) => R | Promise<R>,
  iterable?: AnyIterable<T>,
) {
  if (func === undefined) {
    return <A, B>(curriedFunc: (data: A) => B | Promise<B>, curriedIterable?: AnyIterable<A>) => parallelMap(concurrency, curriedFunc, curriedIterable)
  }
  if (iterable === undefined) {
    return (curriedIterable: AnyIterable<T>) => parallelMap<T, R>(concurrency, func, curriedIterable)
  }
  return _parallelMap<T, R>(concurrency, func, iterable)
}

Спасибо!

1 Ответ

0 голосов
/ 15 ноября 2018

Перегрузки полезны, когда разные типы параметров должны приводить к разным типам возвращаемых значений.Бесполезно иметь две разные сигнатуры перегрузки с одинаковыми типами параметров.Это потому, что, как говорится в справочнике:

[Компилятор] просматривает список перегрузок и, продолжая первую перегрузку, пытается вызвать функцию с предоставленными параметрами.Если он находит совпадение, он выбирает эту перегрузку как правильную перегрузку.

Ваши первые две перегрузки имеют одинаковые типы параметров, поэтому вторая перегрузка никогда не будет использоваться.Это означает, что если вы вызовете parallelMap() с одним аргументом, он вернет функцию с двумя аргументами, и все.Он не возвращает функцию с одним аргументом.

Давайте исправим это.Решение здесь заключается в том, что когда вы вызываете parallelMap() с одним аргументом, вы хотите вернуть перегруженную функцию вместо функции с одним аргументом или двумя аргументами.

Кроме того, вы хотите, чтобы параметры универсального типа были в этой возвращаемой функции, поскольку, когда вы вызываете parallelMap(concurrency), вы не знаете в этот момент, что в итоге будут T и R.

Итак, замените эти первые две подписи следующим:

export function parallelMap(concurrency: number): { 
  <T,R>(func: (data: T) => R | Promise<R>, iterable: AnyIterable<T>): AsyncIterableIterator<R>, 
  <T,R>(func: (data: T) => R | Promise<R>): (iterable: AnyIterable<T>) => AsyncIterableIterator<R> 
}

Теперь, когда написано "если вы вызываете parallelMap() с одним аргументом, он вернет другую функцию, которая может быть вызвана с двумя аргументами:введите XXX и YYY, верните ZZZ, и его также можно вызвать с одним аргументом типа XXX и вернуть функцию из YYY в ZZZ. "

Теперь это должно работать в основном.Обратите внимание, что, поскольку вы используете перегрузки, следующий код не совсем корректен:

  if (func === undefined) {
    return <A, B>(
      curriedFunc: (data: A) => B | Promise<B>, 
      curriedIterable?: AnyIterable<A>
    ) => parallelMap(concurrency, curriedFunc, curriedIterable) // error!
  }

В конце концов, ни одна из сигнатур вызова перегрузки не принимает, возможно, undefined третий аргумент.Вы можете вызвать это с двумя или тремя определенными аргументами.Поэтому вы должны изменить это на что-то вроде:

  if (func === undefined) {
    return <A, B>(
      curriedFunc: (data: A) => B | Promise<B>,
      curriedIterable?: AnyIterable<A>
    ) => curriedIterable ?
        parallelMap(concurrency, curriedFunc, curriedIterable) :
        parallelMap(concurrency, curriedFunc)
  }

, которое вызывает две различные перегрузки parallelMap() в зависимости от того, определено ли curriedIterable.

Хорошо, надеюсь, это поможет.Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...