preface

In recent days, I was reading elevation, and I was a little confused about the concept, so I looked for the relevant tutorial, hoping that I could understand it and possibly use it. This article mainly refers to Hu Yu’s blog to familiarize myself with these two concepts in a way I can understand.

Currie,

What is Corrification? From Hu Yu’s blog – a feature on JavaScript called Function Coriolization

In mathematics and computer science, Currization is the technique of converting a function that takes multiple arguments into a series of functions that take one argument.

For example

This example is from Fun Fun Function-YouTube

Let’s take a normal function

let dragon = (name, size, element) = > {
  return `${name} is a ${size} dragon that breathes ${element}! `;
};

console.log(dragon("Karo"."large"."ice"));
// Karo is a large dragon that breathes ice!
Copy the code

Simulation of the Currie process

let dragon = name= > size => element= >
  `${name} is a ${size} dragon that breathes ${element}! `;
console.log(dragon('Karo') ('large') ('ice'));
// Karo is a large dragon that breathes ice!
Copy the code

The realization of Currization in elevation

function curry(fn) {
  var args = Array.prototype.slice.call(arguments.1);
  return function() {
    var innerArgs = Array.prototype.slice.call(arguments);
    var finalArgs = args.concat(innerArgs);
    return fn.apply(null, finalArgs); }}let dragon = (name, size, element) = > {
  return `${name} is a ${size} dragon that breathes ${element}! `;
};
dragon = curry(dragon);
let fluffykinsDragon = dragon('fluffykins'); // The curyy function can only save one parameter and then return it
// fluffykins is a undefined dragon that breathes undefined!
// An error is reported if the following statement is executed:
// let tinyDragon = fluffykinsDragon("tiny"); An error
Copy the code

How do you implement the Currization function?

Using the example above, let’s start with the first edition

The first edition of Corrification

/ / the first edition
function curry(fn) {
  var args = [];
  return function() {
    args = args.concat([].slice.call(arguments));
    return function() {
      args = args.concat([].slice.call(arguments));
      return function() {
        args = args.concat([].slice.call(arguments));
        return fn.apply(null, args); }}}; }Copy the code

Test the

/ / test
let dragon = (name, size, element) = > {
  return `${name} is a ${size} dragon that breathes ${element}! `;
};
dragon = curry(dragon);
let fluffykinsDragon = dragon("fluffykins");
let tinyDragon = fluffykinsDragon("tiny");
console.log(tinyDragon("ice"));
// fluffykins is a tiny dragon that breathes ice!
Copy the code

If there are too many arguments, then there is infinite nesting, so the second version uses recursive optimization

The Second edition of Cremation

/ / the second edition
function curry(fn, args, length) {
  length = length || fn.length;
  args = args || [];
  return function() {
    args = args.concat([].slice.call(arguments));
    if (arguments.length < length) {
      return curry(fn, args, length - arguments.length);
    }
    return fn.apply(this, args); }}Copy the code

We found that Curry (FN, ARgs, Length-1) had three parameters, and we used the elevation example as an intermediate function to optimize it further, hence the third edition

Cremation third edition

/ / the third edition
function sub_curry(fn) {
  var args = Array.prototype.slice.call(arguments.1);
  return function() {
    var innerArgs = Array.prototype.slice.call(arguments);
    var finalArgs = args.concat(innerArgs);
    return fn.apply(null, finalArgs); }}function curry(fn, length) {
  length = length || fn.length;
  return function() {
    if (arguments.length < length) {
      var args = [fn].concat([].slice.call(arguments));
      return curry(sub_curry.apply(this, args), length - arguments.length);
    }
    return fn.apply(this.arguments);
  };
}
Copy the code

Use ES6 to rewrite it and optimize it

function sub_curry(fn, ... args) {
  return (. args1) = >fn(... args, ... args1); }function curry(fn, length) {
  length = length || fn.length;
  return (. args) = > {
    if (args.length < length) {
      returncurry(sub_curry(fn, ... args), length - args.length); }returnfn(... args); }; }Copy the code

Intersperse 1

I’ve currified the args argument, and now I’m going to get rid of the length argument

function curry(fn, args) {
  var length = fn.length;

  args = args || [];
  return function() {
    var _args = args.concat([].slice.call(arguments));
    if (_args.length < length) {
      return curry.call(this, fn, _args);
    }
    return fn.apply(this, _args);
  };
}
Copy the code

Let me interject 2 — I see a cleaner way of writing it

function curry(fn) {
  return judge = (. args) = > {
    returnargs.length === fn.length ? fn(... args) :(. arg) = >judge(... args, ... arg); }; }Copy the code

The Fourth edition of Cremation

Parameters contain placeholders

/ / the fourth edition
function curry(fn, args) {
  var length = fn.length;
  args = args || [];
  return function() {
    var newArgs = [].slice.call(arguments);
    for (var i = 0, len = args.length; i < len; i++) {
      if (args[i] === _) {
        args.splice(i, 1, newArgs.shift());
      }
      if (newArgs.length === 0) break;
    }
    var _args = args.concat(newArgs);
    var _filterArr = _args.filter(ele= >ele ! = = _);if (_filterArr.length < length) {
      return curry.call(this, fn, _args);
    }
    return fn.apply(this, _args);
  };
}
Copy the code

Test the

var fn = curry(function(a, b, c, d, e) {
  console.log([a, b, c, d, e]);
});
var _ = {};
// The output is [1, 2, 3, 4, 5]
fn(1.2.3.4.5);
fn(_, 2.3.4.5) (1);
fn(1, _, 3.4.5) (2);
fn(1, _, 3) (_,4) (2) (5);
fn(1, _, _, 4) (_,3) (2) (5);
fn(_, 2) (_, _,4) (1) (3) (5);
Copy the code

Partial function

What is a partial function? Again from Hu Yu’s blog

In computer science, a local application is to fix some parameters of a function and then produce another function with smaller elements.

The transformation of a multi-parameter function into multiple single-parameter functions is to convert an n-yuan function into n unary functions.

Local applications fix one or more parameters of a function, that is, convert an n-yuan function to an n-x yuan function.

Partial functions first edition

// This is the elevation example
function partial(fn) {
  var args = Array.prototype.slice.call(arguments.1);
  return function() {
    var innerArgs = Array.prototype.slice.call(arguments);
    var finalArgs = args.concat(innerArgs);
    return fn.apply(null, finalArgs); }}Copy the code

Partial functions, second edition

var _ = {};
function partial(fn) {
  var args = [].slice.call(arguments.1);
  return function() {
    var len = args.length;
    var _args = [].slice.call(arguments);
    for(var i = 0; i < len; i++) {
      args[i] = args[i] === _ ? _args.shift() : args[i];
      if (_args.length === 0) break;
    }
    args.concat(_args);
    return fn.apply(this, args); }}Copy the code

Test the

var subtract = function(a, b, c) {
  return b - a + c;
};
var subFrom20 = partial(subtract, 5, _, _);
console.log(subFrom20(15.5.5)); / / 15
Copy the code

To summarize

Through the tutorial and their own understanding of the preliminary understanding of coriolization and partial function, as for the specific use of the scene, may be used to know.

Refer to the tutorial

  • Hu Yu’s blog – The Function Coriolization of the JavaScript topic
  • Hu Yu’s blog – Partial functions of JavaScript topics
  • Fun Fun Function
  • Cover photo

Personal blog

Tony’s blog