前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >函数curry化(Haskell Curry)

函数curry化(Haskell Curry)

作者头像
elson
发布2020-01-02 16:01:36
1.2K0
发布2020-01-02 16:01:36
举报
文章被收录于专栏:Elson's webElson's web

什么是函数curry化?

官方解释 柯里化(Currying),又称部分求值(Partial Evaluation),是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

个人白话文理解

当一个函数fn有多个参数时,可以先传入一部分参数,生成一个中继函数nextFn,然后在nextFn当中再传入剩下的参数。(一步curry化)

代码语言:javascript
复制
function currying(x, y) {
    if (typeof y == 'undefined') {
        return function (y) {
            return x + y;
        };
    }
    else {
        return x + y;
    }
}

var nextFn = currying(5);
console.log(nextFn(5)); // 10

通用curry化函数

代码语言:javascript
复制
function currying(fn) {
    var slice = Array.prototype.slice;
    // 将arguments对象数组化,并排除第一个参数fn
    var args = slice.call(arguments, 1);

    return function () {
        var newArgs = slice.call(arguments);

        return fn.apply(null, args.concat(newArgs));
    };
}
代码语言:javascript
复制
// test
function add(a, b, c, d, e) {
    return a + b + c + d + e;
}

// 一步curry化
var next = currying(add, 11, 22);
// 两步curry化
var next2 = currying(next, 33);
// 三步curry化
var next3 = currying(next2, 44);

next(33, 44, 55); // 165
next2(44, 55); // 165
next3(55); // 165

curry化有什么用

参照:http://www.zhangxinxu.com/wordpress/2013/02/js-currying/

1. 参数复用

curry化之后会返回一个新的函数,这个函数通过闭包保存着重复的参数。

2. 延迟执行

其实ES5当中的Function.prototype.bind方法运用的就是curry化的思想

代码语言:javascript
复制
if (typeof Function.prototype.bind == 'undefined') {
    Function.prototype.bind = function (o) {
        var me = this;
        var args = [].slice.call(arguments, 1);

        return function () {
            var newArgs = [].slice.call(arguments);

            return me.apply(o, args.concat(newArgs));
        };
    };
}

总结

看完curry化,第一个感觉是好高大阿,但是…好像目前没感觉到它有什么用耶。。。

其实我觉得张鑫旭的博客JS中的柯里化当中,有段话讲的挺有道理的

最近在看《JavaScript模式》一书,天哪,里面出现的各种设计模式(如工厂模式、外观模式、观察者模式),一双手都数不过来。而且这些名词又很抽象,书一合,马上大眼瞪小眼了。这种感觉就像是,房间里来了10个黑人,每个黑人都有一个“¥%#…¥”的名字,好不容易勉强记住了,灯一关房间一黑,等再开灯的时候,每个黑人的名字都变成…..”hello”了。 其实这些模式在实际使用的时候,或多或少都使用过,当看到“xx模式”概念的时候,我们就会猛然惊起:“哦,原来这个就叫做‘观察者模式’等”。现在要讨论的问题是,我们有没有必要把这些“xx模式”都记住呢,都理解其对应的核心呢? 这个问题类似于,我可以看懂NBA的篮球比赛,那我有没有必要把各个球队以及球队的队员都记住呢? 如果想成为JS大神,从这个目标来看,这是需要的;好比优秀的篮球解说员必须要知道每个球队的名字、球员甚至周边八卦。但是,现实很重要。如果连JS函数相关的基本东西都驾驭不好,显然,硬是啃这些似懂非懂的概念只会造成混乱。如果你觉得可以更近一步,先通透几个自己习惯的熟悉的使用模式,足够应付实际项目;其他一些概念什么的,更多的只是噱头,实用性其实并不大。 正如本文的柯里化,看上去很高级,似乎也有点用处,然而JS的灵活性使得很多实现完全摆脱“柯里化”这个概念的束缚,以更通俗易懂的方式实现。 然而,即使实用性不高,我们还是要有所了解,因为,你不知道什么时候会用到它。比方说CSS中的 display:table; 某些情况下可以解决一些棘手问题(secret!)。 因此,本文的柯里化至少要知道个大概…


代码语言:txt
复制
                 var gitalk = new Gitalk({                     clientID: '82f3fb6574634b43d203',                     clientSecret: '5790d9fdbfe9340d29810b694b3b2070a9a3b492',                     repo: 'zfengqi.github.io',                     owner: 'zfengqi',                     admin: ['zfengqi'],                     distractionFreeMode: true,                     id: window.location.pathname,                     });                     gitalk.render('gitalk-container');
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是函数curry化?
  • 通用curry化函数
  • curry化有什么用
    • 1. 参数复用
      • 2. 延迟执行
      • 总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档