Javascript функциональная композиция / секвенирование - PullRequest
0 голосов
/ 20 апреля 2020

Я пытаюсь понять композицию и концепцию «секвенирования» в Javascript с помощью упражнения:

Def. "состав" compose(f,g)(x) = f(g(x))

Def. "последовательность" sequence(f,g)(x) = g(f(x)) для большего количества аргументов sequence(f,g)(...args) = g(f(...args))

const sequence2 = (f1, f2) => (...args) => f2( f1(...args) );
const sequence = (f1, ...fRest) => fRest.reduce(sequence2, f1);

const f1 = (a, b) => {
    console.log(`[f1] working on: ${a} and ${b}`);
    return a + b;
}

const f2 = a => `Result is ${a}`;

const sequenceResult = sequence(f1, f1, f2)(1, 2, 5);
console.log(sequenceResult);

Консоль показывает:

[f1] working on: 1 and 2
[f1] working on: 3 and undefined
Result is NaN

Кажется, что вторая функция в последовательности может получить доступ к аргументам: что-то мне не хватает или это неправильный подход к работе с параметрами? (Функция последовательности работает для функций без параметров).

Здесь JSFiddle

Ответы [ 2 ]

1 голос
/ 20 апреля 2020

Функции возвращают только одно значение. Есть два способа дополнить функции несколькими возвращаемыми значениями:

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

Вот забавная реализация для последнего, которая явно не предназначена для любого производственного кода:

const pipek = g => f => x => y => k =>
  k(g(x) (y) (f));

const addk = x => y => k =>
  (console.log("apply addk to", x, y), k(x + y));

const main = pipek(addk)
  (addk)
    (2)
      (3)
        (k => k(4)); // we have to pass the 4th argument within the continuation

console.log(main(x => x)); // escape from the continuation

Обратите внимание, что все функции являются карри и что я использовал термин pipe, который является обычным термином для композиции обратных функций в JS.

1 голос
/ 20 апреля 2020

Кажется, что вторая функция в последовательности не может получить доступ к аргументам

Да, это нормально и ожидаемо. Согласно определению, которое вы дали,

sequence(f1, f1, f2)(1, 2, 5);

эквивалентно

f2(f1(f1(1, 2, 5)));

Конечно, ни f2, ни внешний f1 не могут получить доступ к аргументам, которые передаются внутреннему f1.

...