摘要:前面兩節(jié)介紹了純函數(shù)和高階函數(shù),在函數(shù)式編程中,函數(shù)就是我們的磚塊。參數(shù)順序是能否最大程度利用柯里化的關(guān)鍵所在。
前面兩節(jié)介紹了純函數(shù)和高階函數(shù),在函數(shù)式編程中,函數(shù)就是我們的磚塊。我們編寫一些可以完成非常具體任務(wù)的函數(shù),然后像樂(lè)高積木一樣將他們搭建起來(lái)。
這就是所謂的函數(shù)組合。
函數(shù)組合先看兩個(gè)純函數(shù)
let add10 = value => value + 10; let mult5 = value => value * 5; let mult5AfterAdd10 = value => mult5(add10(value))
這樣寫代碼很容易寫出h(g(f(e(x)))),這樣層層相套的代碼,一層一層撥開它的心。
為了解函數(shù)嵌套的問(wèn)題,我們可以先預(yù)定義一個(gè)組合函數(shù)
var compose = function(f,g) { return function(x) { return f(g(x)); }; };
然后改寫上面的例子
let mult5AfterAdd10 = compose(mult5, add10) mult5AfterAdd10(5)
這樣做的可讀性遠(yuǎn)遠(yuǎn)高于嵌套一大堆的函數(shù)調(diào)用。
Point Free把一些對(duì)象自帶的方法轉(zhuǎn)化為純函數(shù),不要命名轉(zhuǎn)瞬即逝的中間變量
網(wǎng)上有很多關(guān)于Point Free的案例,我認(rèn)為都不怎么能說(shuō)明問(wèn)題,下面這個(gè)例子是我精心準(zhǔn)備的機(jī)密,一般不外傳。
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") //我們沒(méi)有使用到str變量
我們不需要指定冗余的參數(shù)。由于不必指定參數(shù),所以也就不必考慮為它們命名。其次,由于更簡(jiǎn)短使得更容易閱讀。Pointfree 的本質(zhì)就是使用一些通用的函數(shù),組合出各種復(fù)雜運(yùn)算。上層運(yùn)算不要直接操作數(shù)據(jù),而是通過(guò)底層函數(shù)去處理。這就要求,將一些常用的操作封裝成函數(shù)。所以說(shuō)這種方式慎用。
看到這里你是不是以為自己就了解函數(shù)式編程了呢?nonono?下面我有個(gè)問(wèn)題想考考你。
let add = (value, y) => value + y; let mult5 = value => value * 5;
我想改寫上面的mult5AfterAdd10函數(shù),把它轉(zhuǎn)成更通用的mult5AfterAdd,你想到用上面學(xué)到的姿勢(shì),
let mult5AfterAdd = compose(mult5, add)
顯然這個(gè)不行的,因?yàn)閍dd函數(shù)需要接收兩個(gè)參數(shù),實(shí)際只傳遞了一個(gè)參數(shù),所以它會(huì)將一個(gè)錯(cuò)誤的結(jié)果傳遞給mult5。這最終會(huì)產(chǎn)生一個(gè)錯(cuò)誤的結(jié)果。
我們?cè)趺唇鉀Q這個(gè)問(wèn)題?事實(shí)證明有一種方法,它就是柯里化(Currying)。
下面我們來(lái)看看函數(shù)的柯里化。
有這樣一道題目,實(shí)現(xiàn)一個(gè)函數(shù),實(shí)現(xiàn)如下功能:
var result = sum(1)(2)(3); console.log(result);//6
以下是一種實(shí)現(xiàn)方式
function add(a){ var sum = 0; sum += a; return b => { sum += b; return c => { sum += c; return sum; } } } add(1)(2)(3);//6
我們來(lái)解決上面遺留的問(wèn)題,通過(guò)改寫add函數(shù)
let add = x => y => x + y let compose = (f, g) => x => f(g(x)); let mult5AfterAdd10 = compose(mult5, add(10));
我們就是將簡(jiǎn)單常見的add函數(shù)轉(zhuǎn)化成了柯里化函數(shù),這樣add函數(shù)就變得更加自由靈活了。我們先將第1個(gè)參數(shù)10輸入,而當(dāng)mult5AfterAdd10函數(shù)被調(diào)用的時(shí)候,最后1個(gè)參數(shù)才有了確定的值。
柯里化柯里化通常也稱部分求值,其含義是給函數(shù)分步傳遞參數(shù),每次傳遞參數(shù)后,部分應(yīng)用參數(shù),并返回一個(gè)更具體的函數(shù)接受剩下的參數(shù),中間可嵌套多層這樣的接受部分參數(shù)函數(shù),逐步縮小函數(shù)的適用范圍,逐步求解,直至返回最后結(jié)果。
一個(gè)簡(jiǎn)單的通用模塊的函數(shù)柯里化封裝
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; } }
函數(shù)柯里化是一種預(yù)加載函數(shù)的方法,通過(guò)傳遞較少的參數(shù),得到一個(gè)已經(jīng)記住了這些參數(shù)的新函數(shù),某種意義上來(lái)講,這是一種對(duì)參數(shù)的“緩存”,是一種非常高效的編寫函數(shù)的方法。??參數(shù)順序是能否最大程度利用柯里化的關(guān)鍵所在。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/82886.html
摘要:子類不是父類實(shí)例的問(wèn)題是由類式繼承引起的。所以寄生式繼承和構(gòu)造函數(shù)繼承的組合又稱為一種新的繼承方式。但是這里的寄生式繼承處理的不是對(duì)象,而是類的原型??瓷先ヂ晕?fù)雜,還得好好研究。 寄生組合式繼承(終極繼承者) 前面學(xué)習(xí)了類式繼承和構(gòu)造函數(shù)繼承組合使用,也就是組合繼承,但是這種繼承方式有個(gè)問(wèn)題,就是子類不是父類的實(shí)例,而子類的原型是父類的實(shí)例。子類不是父類實(shí)例的問(wèn)題是由類式繼承引起的。...
摘要:它大致概述并討論了前端工程的實(shí)踐如何學(xué)習(xí)它,以及在年實(shí)踐時(shí)使用什么工具。目的是每年發(fā)布一次內(nèi)容更新。前端實(shí)踐第一部分廣泛描述了前端工程的實(shí)踐。對(duì)大多數(shù)人來(lái)說(shuō),函數(shù)式編程看起來(lái)更加自然。 1 Front-End Developer Handbook 2017 地址:https://frontendmasters.com/b... 這是任何人都可以用來(lái)了解前端開發(fā)實(shí)踐的指南。它大致概述并...
摘要:它大致概述并討論了前端工程的實(shí)踐如何學(xué)習(xí)它,以及在年實(shí)踐時(shí)使用什么工具。目的是每年發(fā)布一次內(nèi)容更新。前端實(shí)踐第一部分廣泛描述了前端工程的實(shí)踐。對(duì)大多數(shù)人來(lái)說(shuō),函數(shù)式編程看起來(lái)更加自然。 1 Front-End Developer Handbook 2017 地址:https://frontendmasters.com/b... 這是任何人都可以用來(lái)了解前端開發(fā)實(shí)踐的指南。它大致概述并...
摘要:它大致概述并討論了前端工程的實(shí)踐如何學(xué)習(xí)它,以及在年實(shí)踐時(shí)使用什么工具。目的是每年發(fā)布一次內(nèi)容更新。前端實(shí)踐第一部分廣泛描述了前端工程的實(shí)踐。對(duì)大多數(shù)人來(lái)說(shuō),函數(shù)式編程看起來(lái)更加自然。 1 Front-End Developer Handbook 2017 地址:https://frontendmasters.com/b... 這是任何人都可以用來(lái)了解前端開發(fā)實(shí)踐的指南。它大致概述并...
摘要:函數(shù)式編程,一看這個(gè)詞,簡(jiǎn)直就是學(xué)院派的典范。所以這期周刊,我們就重點(diǎn)引入的函數(shù)式編程,淺入淺出,一窺函數(shù)式編程的思想,可能讓你對(duì)編程語(yǔ)言的理解更加融會(huì)貫通一些。但從根本上來(lái)說(shuō),函數(shù)式編程就是關(guān)于如使用通用的可復(fù)用函數(shù)進(jìn)行組合編程。 showImg(https://segmentfault.com/img/bVGQuc); 函數(shù)式編程(Functional Programming),一...
閱讀 5019·2021-11-15 11:39
閱讀 2765·2021-11-11 16:55
閱讀 2264·2021-10-25 09:44
閱讀 3576·2021-09-22 16:02
閱讀 2491·2019-08-30 15:55
閱讀 3190·2019-08-30 13:46
閱讀 2768·2019-08-30 13:15
閱讀 2018·2019-08-30 11:12