Существует ли правильное имя функционального программирования для этой функции (f1, f2, val) => f1 (f2 (val), val); - PullRequest
1 голос
/ 15 марта 2020

Я придумал эту функцию (f1, f2, val) => f1 (f2 (val), val) (javascript нотация), и казалось, что она будет полезна / распространена для функционального программирования. Я хотел знать, если эта функция уже существует, и если она делает то, что ее собственное имя будет.

(эквивалентный вопрос будет то, что (f1, f2, val) => f1 (f2 (val)) называется? и эквивалентный ответ будет композиция)

Ответы [ 5 ]

2 голосов
/ 15 марта 2020

Это просто оператор связывания (>> =) монады функции.

В Haskell функция представлена ​​как a -> b, которую можно рассматривать как оператор (->), принимающий два параметра и переписан как (->) a b. Мы можем частично применить (->) с одним параметром, (->) a.

(->) a - функтор и монада. Как монада, это определение равно

instance Monad ((->) r) where
    f >>= k = \ r -> k (f r) r

В ramda это цепочка функция.

0 голосов
/ 15 марта 2020

Это функция chain API монады, специализированная для типа функции. Преимущество монад в том, что вы можете применять их для любого типа механическим способом, и они всегда работают как положено:

// your combinator in curried form with the two first arguments flipped
const chain = g => f => x => f(g(x)) (x);

// 2nd part of the monad interface
const of = x => _ => x;

const add = x => y => x + y;

/* ridiculously complicated Fibonacci algorithm
   just to demonstrate the predictability of monads */

const fib = n =>
  n > 1
    ? chain(of(n - 1)) (w =>
        chain(of(n - 2)) (x =>
          chain(fib(w)) (y =>
            chain(fib(x)) (z =>
              of(y + z)))))
    : of(n);

const main = fib(10);

console.log(
  main()); // 55

После того, как вы поняли, как работают монады, уже не сложно понять данный пример для типа функции и любой пример для любого типа, который реализует класс типа монады. .

0 голосов
/ 15 марта 2020

Похоже на вариант комбинатора S:

const S = f => g => x => f (x) (g (x))

Возможно, вы сможете реорганизовать свой код для размещения в комбинаторе S.

0 голосов
/ 15 марта 2020

Первый пример выглядит как функция ветвления / конвергенции, где второй аргумент просто передается как тождество.

const a = (f1, f2, val) => f1(f2(val), val);
const b = (f1, f2, val) => R.converge(f1, [f2, R.identity])(val);

const f1 = (a, b) => a + b;
const f2 = (a) => a * 2;

console.log(
  a(f1, f2, 50),
);

console.log(
  b(f1, f2, 50),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js" integrity="sha256-buL0byPvI/XRDFscnSc/e0q+sLA65O9y+rbF+0O/4FE=" crossorigin="anonymous"></script>

Второй пример - это просто составная функция ...

const a = (f1, f2, val) => f1(f2(val));
 
const f1 = (a) => a * 2;
const f2 = (a) => a + 100;
 
console.log(
  a(f1, f2, 50),
);
 
console.log(
  R.compose(f1, f2)(50),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js" integrity="sha256-buL0byPvI/XRDFscnSc/e0q+sLA65O9y+rbF+0O/4FE=" crossorigin="anonymous"></script>
0 голосов
/ 15 марта 2020

Для меня это выглядит как цепочка метода Рамды:

Если второй аргумент является функцией, цепочка (f, g) (x) эквивалентна f (g ( x), x).

Итак:

R.chain(R.append, R.sum)([1, 2, 3]);

похож на:

R.append(R.sum([1, 2, 3]), [1, 2, 3]);
//=> [1, 2, 3, 6]

Является ли общее имя для такого шаблона chain Я не уверена. Функциональное программирование иногда имеет непроницаемый лин go ИМХО.

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