How to implement the exquisite automatic currying function in JS
This article gives you a detailed analysis of the exquisite automatic currying method in JS and analyzes the process and principles through code examples. Please refer to it and study it. I hope it can help you.
What is currying?
In computer science, currying is to transform a function that accepts multiple parameters into a function that accepts a single parameter (the first parameter of the original function), and returns the remaining parameters. The technique of a new function that takes arguments and returns a result. This technique was named by Christopher Strachey after logician Haskell Curry, although it was invented by Moses Schnfinkel and Gottlob Frege.
The theory seems overwhelming? It doesn’t matter, let’s take a look at the code first:
Curriization application
Suppose we need to implement a function that performs some processing on list elements, for example, let each element in the list add One, then it’s easy to think of:
const list = [0, 1, 2, 3]; list.map(elem => elem + 1);
It’s very simple, right? What if we want to add 2 more?
const list = [0, 1, 2, 3]; list.map(elem => elem + 1); list.map(elem => elem + 2);
It seems that the efficiency is a bit low. Can the processing function be encapsulated?
But the callback function of map only accepts the current element elem as a parameter. It seems that there is no way to encapsulate it...
You may think: If you can get a partial configuration A good function is fine, for example:
// plus返回部分配置好的函数 const plus1 = plus(1); const plus2 = plus(2); plus1(5); // => 6 plus2(7); // => 9
Pass such a function into the map:
const list = [0, 1, 2, 3]; list.map(plus1); // => [1, 2, 3, 4] list.map(plus2); // => [2, 3, 4, 5]
Isn’t it great? In this way, no matter how much you add, you only need list.map(plus(x)), which perfectly implements encapsulation and greatly improves readability!
But here comes the question: How to implement such a plus function?
This is where currying comes in handy:
currying function
// 原始的加法函数 function origPlus(a, b) { return a + b; } // 柯里化后的plus函数 function plus(a) { return function(b) { return a + b; } } // ES6写法 const plus = a => b => a + b;
You can see , the curried plus function first accepts a parameter a, and then returns a function that accepts a parameter b. Due to closure, the returned function can access the parameter a of the parent function, so for example: const plus2 = plus (2) can be equivalent to function plus2(b) { return 2 + b; }, thus achieving partial configuration.
In layman's terms, currying is a process of partially configuring a multi-parameter function, with each step returning a partially configured function that accepts a single parameter. In some extreme cases, you may need to partially configure a function many times, such as multiple additions:
multiPlus(1)(2)(3); // => 6
This way of writing seems strange, right? But if you fall into the big pit of functional programming in JS, this will be the norm.
Exquisite implementation of automatic currying in JS
Currying is a very important part of functional programming. Many functional languages (eg. Haskell) automatically curry functions by default. However, JS does not do this, so we need to implement the automatic currying function ourselves.
First enter the code:
// ES5 function curry(fn) { function _c(restNum, argsList) { return restNum === 0 ? fn.apply(null, argsList) : function(x) { return _c(restNum - 1, argsList.concat(x)); }; } return _c(fn.length, []); } // ES6 const curry = fn => { const _c = (restNum, argsList) => restNum === 0 ? fn(...argsList) : x => _c(restNum - 1, [...argsList, x]); return _c(fn.length, []); } /***************** 使用 *********************/ var plus = curry(function(a, b) { return a + b; }); // ES6 const plus = curry((a, b) => a + b); plus(2)(4); // => 6
This achieves automatic currying!
If you can understand what happened, then congratulations! The boss everyone calls you is you! , please leave a like and start your functional career (funny
If you don’t understand what’s going on, don’t worry, I will help you sort out your ideas now.
Requirements Analysis
We need a curry function, which accepts a function to be curried as a parameter, returns a function for receiving a parameter, and puts the received parameters into a list. When the parameter When the number is sufficient, the original function is executed and the result is returned.
Implementation method
Simply thinking, we can know that the number of steps of the curried partial configuration function is equal to the number of parameters of fn. That is to say, the plus function with two parameters needs to be partially configured in two steps. The number of parameters of the function can be obtained through fn.length
The general idea is to put the parameter in every time a parameter is passed. In a parameter list argsList, if there are no parameters to be passed, then fn.apply(null, argsList) is called to execute the original function. To achieve this, we need an internal judgment function _c(restNum, argsList). ), the function accepts two parameters, one is the number of remaining parameters restNum, and the other is the list of obtained parameters argsList; the function of _c is to determine whether there are any parameters that have not been passed in. When restNum is zero, it is time to pass fn.apply(null, argsList) executes the original function and returns the result. If there are still parameters that need to be passed, that is, when restNum is not zero, a single-parameter function needs to be returned.
function(x) { return _c(restNum - 1, argsList.concat(x)); }
to continue receiving parameters. A tail recursion is formed here. After the function accepts a parameter, the number of remaining parameters restNum is reduced by one, and the new parameter x is added to argsList and passed to _c for recursion. Call. The result is that when the number of parameters is insufficient, the single-parameter function responsible for receiving new parameters is returned. When there are enough parameters, the original function is called and returned:
function curry(fn) { function _c(restNum, argsList) { return restNum === 0 ? fn.apply(null, argsList) : function(x) { return _c(restNum - 1, argsList.concat(x)); }; } return _c(fn.length, []); // 递归开始 }
Is it starting to become clearer?
The ES6 writing method looks much simpler due to the use of syntactic sugar such as array destructuring and arrow functions, but the idea is the same. Same~
// ES6 const curry = fn => { const _c = (restNum, argsList) => restNum === 0 ? fn(...argsList) : x => _c(restNum - 1, [...argsList, x]); return _c(fn.length, []); }
Comparison with other methods
There is another commonly used method:
function curry(fn) { const len = fn.length; return function judge(...args1) { return args1.length >= len ? fn(...args1): function(...args2) { return judge(...[...args1, ...args2]); } } } // 使用箭头函数 const curry = fn => { const len = fn.length; const judge = (...args1) => args1.length >= len ? fn(...args1) : (...args2) => judge(...[...args1, ...args2]); return judge; }
Compared with the method mentioned previously in this article, it is found that this method has two problems:
Relies on ES6 destructuring (the function parameter ...args1 and ...args2);
性能稍差一点。
性能问题
做个测试:
console.time("curry"); const plus = curry((a, b, c, d, e) => a + b + c + d + e); plus(1)(2)(3)(4)(5); console.timeEnd("curry");
在我的电脑(Manjaro Linux,Intel Xeon E5 2665,32GB DDR3 四通道1333Mhz,Node.js 9.2.0)上:
本篇提到的方法耗时约 0.325ms
其他方法的耗时约 0.345ms
差的这一点猜测是闭包的原因。由于闭包的访问比较耗性能,而这种方式形成了两个闭包:fn 和 len,前面提到的方法只形成了 fn 一个闭包,所以造成了这一微小的差距。
相关推荐:
The above is the detailed content of How to implement the exquisite automatic currying function in JS. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



There will be many AI creation functions in the Doubao app, so what functions does the Doubao app have? Users can use this software to create paintings, chat with AI, generate articles for users, help everyone search for songs, etc. This function introduction of the Doubao app can tell you the specific operation method. The specific content is below, so take a look! What functions does the Doubao app have? Answer: You can draw, chat, write articles, and find songs. Function introduction: 1. Question query: You can use AI to find answers to questions faster, and you can ask any kind of questions. 2. Picture generation: AI can be used to create different pictures for everyone. You only need to tell everyone the general requirements. 3. AI chat: can create an AI that can chat for users,

Both vivox100s and x100 mobile phones are representative models in vivo's mobile phone product line. They respectively represent vivo's high-end technology level in different time periods. Therefore, the two mobile phones have certain differences in design, performance and functions. This article will conduct a detailed comparison between these two mobile phones in terms of performance comparison and function analysis to help consumers better choose the mobile phone that suits them. First, let’s look at the performance comparison between vivox100s and x100. vivox100s is equipped with the latest

With the rapid development of the Internet, the concept of self-media has become deeply rooted in people's hearts. So, what exactly is self-media? What are its main features and functions? Next, we will explore these issues one by one. 1. What exactly is self-media? We-media, as the name suggests, means you are the media. It refers to an information carrier through which individuals or teams can independently create, edit, publish and disseminate content through the Internet platform. Different from traditional media, such as newspapers, television, radio, etc., self-media is more interactive and personalized, allowing everyone to become a producer and disseminator of information. 2. What are the main features and functions of self-media? 1. Low threshold: The rise of self-media has lowered the threshold for entering the media industry. Cumbersome equipment and professional teams are no longer needed.

As Xiaohongshu becomes popular among young people, more and more people are beginning to use this platform to share various aspects of their experiences and life insights. How to effectively manage multiple Xiaohongshu accounts has become a key issue. In this article, we will discuss some of the features of Xiaohongshu account management software and explore how to better manage your Xiaohongshu account. As social media grows, many people find themselves needing to manage multiple social accounts. This is also a challenge for Xiaohongshu users. Some Xiaohongshu account management software can help users manage multiple accounts more easily, including automatic content publishing, scheduled publishing, data analysis and other functions. Through these tools, users can manage their accounts more efficiently and increase their account exposure and attention. In addition, Xiaohongshu account management software has

"Exploring Discuz: Definition, Functions and Code Examples" With the rapid development of the Internet, community forums have become an important platform for people to obtain information and exchange opinions. Among the many community forum systems, Discuz, as a well-known open source forum software in China, is favored by the majority of website developers and administrators. So, what is Discuz? What functions does it have, and how can it help our website? This article will introduce Discuz in detail and attach specific code examples to help readers learn more about it.

PHP Tips: Quickly implement the function of returning to the previous page. In web development, we often encounter the need to implement the function of returning to the previous page. Such operations can improve the user experience and make it easier for users to navigate between web pages. In PHP, we can achieve this function through some simple code. This article will introduce how to quickly implement the function of returning to the previous page and provide specific PHP code examples. In PHP, we can use $_SERVER['HTTP_REFERER'] to get the URL of the previous page

Detailed explanation of the functions and functions of GDM under Linux In the Linux operating system, GDM (GNOMEDisplayManager) is a graphical login manager that provides an interface for users to log in and log out of the system. GDM is usually part of the GNOME desktop environment, but can be used by other desktop environments as well. The role of GDM is not only to provide a login interface, but also includes user session management, screen saver, automatic login and other functions. The functions of GDM mainly include the following aspects:

If you are using a Linux operating system and want the system to automatically mount the drive on boot, you can do this by adding the device's unique identifier (UID) and mount point path to the fstab configuration file. fstab is a file system table file located in the /etc directory. It contains information about the file systems that need to be mounted when the system starts. By editing the fstab file, you can ensure that the required drives are loaded correctly every time the system starts, thus ensuring stable system operation. Automatically mounting drivers can be conveniently used in a variety of situations. For example, I plan to back up my system to an external storage device. To achieve automation, ensure that the device remains connected to the system, even at startup. Likewise, many applications will directly
