摘要:前面两节介绍了纯函数和高阶函数,在函数式编程中,函数就是我们的砖块。参数顺序是能否最大程度利用柯里化的关键所在。
前面两节介绍了纯函数和高阶函数,在函数式编程中,函数就是我们的砖块。我们编写一些可以完成非常具体任务的函数,然后像乐高积木一样将他们搭建起来。
这就是所谓的函数组合。
函数组合先看两个纯函数
let add10 = value => value + 10; let mult5 = value => value * 5; let mult5AfterAdd10 = value => mult5(add10(value))
这样写代码很容易写出h(g(f(e(x)))),这样层层相套的代码,一层一层拨开它的心。
为了解函数嵌套的问题,我们可以先预定义一个组合函数
var compose = function(f,g) { return function(x) { return f(g(x)); }; };
然后改写上面的例子
let mult5AfterAdd10 = compose(mult5, add10) mult5AfterAdd10(5)
这样做的可读性远远高于嵌套一大堆的函数调用。
Point Free把一些对象自带的方法转化为纯函数,不要命名转瞬即逝的中间变量
网上有很多关于Point Free的案例,我认为都不怎么能说明问题,下面这个例子是我精心准备的机密,一般不外传。
const f = str => str.toUpperCase().split(""); const toUpperCase = word => word.toUpperCase(); const split = x => (str => str.split(x)); const f = compose(split(""), toUpperCase) f("aa vv") //我们没有使用到str变量
我们不需要指定冗余的参数。由于不必指定参数,所以也就不必考虑为它们命名。其次,由于更简短使得更容易阅读。Pointfree 的本质就是使用一些通用的函数,组合出各种复杂运算。上层运算不要直接操作数据,而是通过底层函数去处理。这就要求,将一些常用的操作封装成函数。所以说这种方式慎用。
看到这里你是不是以为自己就了解函数式编程了呢?nonono?下面我有个问题想考考你。
let add = (value, y) => value + y; let mult5 = value => value * 5;
我想改写上面的mult5AfterAdd10函数,把它转成更通用的mult5AfterAdd,你想到用上面学到的姿势,
let mult5AfterAdd = compose(mult5, add)
显然这个不行的,因为add函数需要接收两个参数,实际只传递了一个参数,所以它会将一个错误的结果传递给mult5。这最终会产生一个错误的结果。
我们怎么解决这个问题?事实证明有一种方法,它就是柯里化(Currying)。
下面我们来看看函数的柯里化。
有这样一道题目,实现一个函数,实现如下功能:
var result = sum(1)(2)(3); console.log(result);//6
以下是一种实现方式
function add(a){ var sum = 0; sum += a; return b => { sum += b; return c => { sum += c; return sum; } } } add(1)(2)(3);//6
我们来解决上面遗留的问题,通过改写add函数
let add = x => y => x + y let compose = (f, g) => x => f(g(x)); let mult5AfterAdd10 = compose(mult5, add(10));
我们就是将简单常见的add函数转化成了柯里化函数,这样add函数就变得更加自由灵活了。我们先将第1个参数10输入,而当mult5AfterAdd10函数被调用的时候,最后1个参数才有了确定的值。
柯里化柯里化通常也称部分求值,其含义是给函数分步传递参数,每次传递参数后,部分应用参数,并返回一个更具体的函数接受剩下的参数,中间可嵌套多层这样的接受部分参数函数,逐步缩小函数的适用范围,逐步求解,直至返回最后结果。
一个简单的通用模块的函数柯里化封装
const curry = fn => { const _args = []; return function cb() { if(arguments.length === 0) { return fn.apply(this, _args); } Array.prototype.push.apply(_args, [...arguments]); return cb; } }
函数柯里化是一种预加载函数的方法,通过传递较少的参数,得到一个已经记住了这些参数的新函数,某种意义上来讲,这是一种对参数的“缓存”,是一种非常高效的编写函数的方法。⚠️参数顺序是能否最大程度利用柯里化的关键所在。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/82886.html
摘要:子类不是父类实例的问题是由类式继承引起的。所以寄生式继承和构造函数继承的组合又称为一种新的继承方式。但是这里的寄生式继承处理的不是对象,而是类的原型。看上去略微复杂,还得好好研究。 寄生组合式继承(终极继承者) 前面学习了类式继承和构造函数继承组合使用,也就是组合继承,但是这种继承方式有个问题,就是子类不是父类的实例,而子类的原型是父类的实例。子类不是父类实例的问题是由类式继承引起的。...
摘要:它大致概述并讨论了前端工程的实践如何学习它,以及在年实践时使用什么工具。目的是每年发布一次内容更新。前端实践第一部分广泛描述了前端工程的实践。对大多数人来说,函数式编程看起来更加自然。 1 Front-End Developer Handbook 2017 地址:https://frontendmasters.com/b... 这是任何人都可以用来了解前端开发实践的指南。它大致概述并...
摘要:它大致概述并讨论了前端工程的实践如何学习它,以及在年实践时使用什么工具。目的是每年发布一次内容更新。前端实践第一部分广泛描述了前端工程的实践。对大多数人来说,函数式编程看起来更加自然。 1 Front-End Developer Handbook 2017 地址:https://frontendmasters.com/b... 这是任何人都可以用来了解前端开发实践的指南。它大致概述并...
摘要:它大致概述并讨论了前端工程的实践如何学习它,以及在年实践时使用什么工具。目的是每年发布一次内容更新。前端实践第一部分广泛描述了前端工程的实践。对大多数人来说,函数式编程看起来更加自然。 1 Front-End Developer Handbook 2017 地址:https://frontendmasters.com/b... 这是任何人都可以用来了解前端开发实践的指南。它大致概述并...
摘要:函数式编程,一看这个词,简直就是学院派的典范。所以这期周刊,我们就重点引入的函数式编程,浅入浅出,一窥函数式编程的思想,可能让你对编程语言的理解更加融会贯通一些。但从根本上来说,函数式编程就是关于如使用通用的可复用函数进行组合编程。 showImg(https://segmentfault.com/img/bVGQuc); 函数式编程(Functional Programming),一...
阅读 4596·2021-11-15 11:39
阅读 2659·2021-11-11 16:55
阅读 2127·2021-10-25 09:44
阅读 3469·2021-09-22 16:02
阅读 2378·2019-08-30 15:55
阅读 3090·2019-08-30 13:46
阅读 2567·2019-08-30 13:15
阅读 1891·2019-08-30 11:12