Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

函数柯里化 #159

Open
S-T-D opened this issue Nov 30, 2021 · 0 comments
Open

函数柯里化 #159

S-T-D opened this issue Nov 30, 2021 · 0 comments

Comments

@S-T-D
Copy link
Owner

S-T-D commented Nov 30, 2021

是什么

在数学和计算机科学中,柯里化是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术。

比如:

function add(a, b, c) {
    return a + b + c;
}

const curried = curry(add);

curried(1)(2)(3);   // output: 6

add 函数是一个多参数函数,经过柯里化后得到 curried 函数。

curried 函数可以接收一个或多个参数,只有当参数个数达到预定的个数的时候才会执行,否则就将参数保存起来,返回一个函数继续接收后续参数。

 

用途

curry 的用途可以理解为:参数复用。本质上是降低通用性,提高适用性。

重点在于降低通用性,提高适用性。

这似乎与平时的编码规范相违背,一般我们都会尽量提高代码的通用性和复用性,而柯里化却要降低通用性。

 

先看两个例子,例子都来自于参考资料。

// 示意而已
function ajax(type, url, data) {
    var xhr = new XMLHttpRequest();
    xhr.open(type, url, true);
    xhr.send(data);
}

// 虽然 ajax 这个函数非常通用,但在重复调用的时候参数冗余
ajax('POST', 'www.test.com', "name=kevin")
ajax('POST', 'www.test2.com', "name=kevin")
ajax('POST', 'www.test3.com', "name=kevin")

// 利用 curry
var ajaxCurry = curry(ajax);

// 以 POST 类型请求数据
var post = ajaxCurry('POST');
post('www.test.com', "name=kevin");

// 以 POST 类型请求来自于 www.test.com 的数据
var postFromTest = post('www.test.com');
postFromTest("name=kevin");

可以看到复用性和柯里化并不冲突,我们仍然需要一个通用的 ajax 函数,但是在具体特定场景大量试用 ajax 的时候,我们可以通过柯里化来简化代码,简化 ajax 的试用,让其更适合在这里试用。

 

var prop = curry(function (key, obj) {
    return obj[key]
});

var name = person.map(prop('name'));

map 是平时开发高频使用的 API,上述代码对 person 数组进行遍历,取出 name 数组。

在这里,柯里化使我们只需要关注 key 属性,除了取 name,还可以取 person 的任意属性,提高了复用性,并且语义清晰。

 

实现

const curry = (fn) => {
    const curried = (...args) => 
        args.length === fn.length ? 
            fn(...args) : (...args2) => curried(...args, ...args2);
    return curried;
}

实现原理就是:参数个数满足就执行,不满足就先保存,继续返回函数以接收新的参数。

 

参考资料

@S-T-D S-T-D changed the title 我理解的——函数柯里化 函数柯里化 Dec 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant