Множество ответов от более широкого сообщества FP могут направить вас немного неправильно. Кармины Рамды, как мне кажется, несут дух currying из языков стиля ML в Javascript, но не являются строго одинаковыми.
Частичное применение, вероятно, довольно стандартное в Рамде. (Отказ от ответственности: я один из авторов Рамды.) Это также намного проще описать. partial
функции Ramda в принимает функцию n
аргументов и список k
аргументов (для некоторых 0 < k < n
), и возвращает новую функцию n - k
аргументов, которые будут вызывать оригинальную функцию с новыми аргументами и оригинальными:
const f = (a, b, c, d, e) => a + b + c + d + e;
// f :: a -> b -> c -> d -> e -> a + b + c + d + e
const g = partial(f, [1, 2]);
g.length; //=> 3
g(3, 4, 5); //=> 15
g(3); //=> NaN ≍ 1 + 2 + 3 + undefined + undefined)
// g :: (c, d, e) -> 1 + 2 + c + d + e
Возвращенная функция представляет собой просто простую функцию остальных параметров. Если вы назовете его слишком маленьким, он будет действовать так, как если бы вы назвали исходную функцию слишком маленькими.
Каррирование - это немного другая история. В many languages функция curry
преобразует функцию параметров n
во вложенную последовательность 1-параметрической функции, так что (a, b, c) => f(a, b, c)
преобразуется в a => (b => (c => f(a, b, c))
, который может быть записан без путаницы как a => b => c => f(a, b, c)
. В Ramda мы немного более гибкие, позволяя вам поставлять столько аргументов, сколько вы выберете при одном вызове, каждый раз возвращаете функцию, пока не получите достаточные полные параметры для удовлетворения исходной функции, после чего мы вызываем это и вернуть это значение. Это, вероятно, проще объяснить на примерах:
const f = (a, b, c, d, e) => a + b + c + d + e;
// f :: a -> b -> c -> d -> e -> a + b + c + d + e
const h5 = curry(f);
h5.length; //=> 5
const h3 = h5(1, 2);
h3.length; //=> 3
h3(3, 4, 5); //=> 15
const h2a = h3(3);
h2a.length; //=> 2
h2a(4, 5); //=> 15
const h2b = h5(1, 2, 3);
h2b.length; //=> 2
h2b(4, 5); //=> 15
const h2c = h5(1)(2, 3);
h2c.length; //=> 2
h2c(4, 5); //=> 15
const h2d = h5(1)(2)(3);
h2d.length; //=> 2
h2d(4, 5); //=> 15
const h1a = h3(3, 4);
h1a.length; //=> 1
h1a(5); //=> 15
const h1b = h2a(4);
h1b.length; //=> 1
h1b(5); //=> 15
// h5 :: (a, b, c, d, e) -> a + b + c + d + e
// :: (a, b, c, d) -> e -> a + b + c + d + e
// :: (a, b, c) -> (d, e) -> a + b + c + d + e
// :: (a, b, c) -> d -> e -> a + b + c + d + e
// :: (a, b) -> (c, d, e) -> a + b + c + d + e
// :: (a, b) -> (c, d) -> e -> a + b + c + d + e
// :: (a, b) -> c -> (d, e) -> a + b + c + d + e
// :: (a, b) -> c -> d -> e -> a + b + c + d + e
// :: a -> (b, c, d, e) -> a + b + c + d + e
// :: a -> (b, c, d) -> e -> a + b + c + d + e
// :: a -> (b, c) -> (d, e) -> a + b + c + d + e
// :: a -> (b, c) -> d -> e -> a + b + c + d + e
// :: a -> b -> (c, d, e) -> a + b + c + d + e
// :: a -> b -> (c, d) -> e -> a + b + c + d + e
// :: a -> b -> c -> (d, e) -> a + b + c + d + e
// :: a -> b -> c -> d -> e -> a + b + c + d + e
Поскольку curry
настолько гораздо более гибким, я редко использую partial
себя. Но есть люди, которые, гм, частично.
Это почти такой же вопрос, как [В чем разница между каррированием и частичным приложением] (http://stackoverflow.com/q/218025/2907849) только без ссылки на рамда. – lonelyelk
@lonelyelk: ... но поскольку «карри» Рамды несколько нестандартные, для этого может потребоваться собственный ответ. Я попробую свои собственные ниже. –