Рамда: Как нормальное приложение перевести на пайп или сочинить

Это вопрос новичка (я все еще новичок в Ramda и функциональном программировании в целом).

У меня есть функция с двумя аргументами. Для простоты предположим, что он просто вычитает числа. Я хочу перевернуть его аргументы. Я понял, как сделать это вручную, но мне кажется, что это можно сделать с помощью pipe или compose, и я не могу понять, как это сделать.

import { curry, flip, pipe } from 'ramda';

const subtract = (a, b) => a - b; // subtract(1, 4); -3
const flippedCurriedSubtract = flip(curry(subtract))
// flippedCurriedSubtract(1)(4); 3

pipe(flip, curry, subtract)(1)(4); // NaN

Как бы вы сделали это с pipe или compose?

РЕДАКТИРОВАТЬ:

pipe(
    curry,
    flip
)(subtract); // works

person J. Hesters    schedule 20.02.2019    source источник
comment
flip сам вычисляет результат. Так что flip((a, b) => a - b) будет работать, как и предполагалось.   -  person Scott Sauyet    schedule 20.02.2019
comment
@ScottSauyet Вау, на самом деле это лучший ответ.   -  person J. Hesters    schedule 20.02.2019
comment
Здесь, в Ramda, мы стремимся доставить удовольствие! Или хотя бы доставить себе удовольствие! ;-)   -  person Scott Sauyet    schedule 20.02.2019
comment
@ScottSauyet Я учусь любить библиотеку (и fp) все больше и больше. Это значительно сокращает количество кода (и, следовательно, количество ошибок) ???? Спасибо за вашу работу.   -  person J. Hesters    schedule 20.02.2019


Ответы (2)


pipe(flip, curry, subtract)(1)(4) невероятно похож на subtract(curry(flip(1)(4)))

Между тем определение flip:

// flip :: (a -> b -> c) -> b -> a -> c 
const flip = curry((fn, a, b) => fn(b, a));

Это означает, что функция flip получит в качестве параметра функцию curry (a -> b -> c), но теперь это число, а затем вызывает ошибку.

pipe(curry,flip)(subtract) равно flip(curry(subtract)), и это подойдет. Он также возвращает то же самое с .compose(flip, curry)(subtract). compose и pipe одинаковы, но отличаются только функцией направления выполнения.

И для новичка. Я рекомендую вам прочитать эту электронную книгу

person bird    schedule 20.02.2019
comment
Я прочитал это и выполнил задания. Очень хорошая книга. Теперь я пытаюсь применить то, что узнал, в реальной жизни. Спасибо за ваш ответ! - person J. Hesters; 20.02.2019

Насколько мне известно, большинство функций в Ramda уже карризованы. Так что вам не нужно снова вычитать карри.

subtract(5, 10); //=> -5
subtract(5)(10); //=> -5

Вы можете flip это, все равно будет карри:

flip(subtract)(5, 10); //=> 5
flip(subtract)(5)(10); //=> 5

Я не думаю, что вам вообще нужна трубка и карри, вы могли бы просто:

const flippedSubtract = flip(subtract);
flippedSubtract(5)(10); //=> 5

Скотт указал в комментариях, что flip автоматически выполняет каррирование не-каррированной функции: (очень полезно)

const foo = (a, b, c) => `foo: ${a}${b}${c}`;
foo('x', 'y', 'z');       //=> 'foo: xyz'
flip(foo)('x')('y')('z'); //=> 'foo: yxz'
person customcommander    schedule 20.02.2019
comment
subtract был просто примером. В реальном мире у меня есть собственная функция (это слишком долго для этого вопроса). Я указал свой собственный subtract в качестве примера, потому что вычитания не коммутативны. Думаю, мне следовало использовать другую функцию, чтобы не путать с subtract Ramda. - person J. Hesters; 20.02.2019
comment
Ах да, в этом случае вам действительно нужно составить карри и флип. - person customcommander; 20.02.2019
comment
flip сам вычисляет результат. Так что flip(myNonCommutativeFunction) будет работать, как и предполагалось. - person Scott Sauyet; 20.02.2019