摘要:在函數(shù)式編程的組合中,我們是從右到左執(zhí)行的,上述的例子中我們借助函數(shù)實(shí)現(xiàn)組合,當(dāng)然,我們也可以用自己的方式實(shí)現(xiàn)。小結(jié)函數(shù)式編程隨著多核的發(fā)展,開始再次出現(xiàn)在我們的視野中,有時(shí)候也會(huì)擔(dān)心過(guò)于吹捧函數(shù)式,反而落入俗套。
程序的本質(zhì)是什么?數(shù)據(jù)結(jié)構(gòu)+算法!!!我想這也是很多程序員給出的答案,我自己也認(rèn)可這一觀點(diǎn),當(dāng)我們了解了某一門編程語(yǔ)之后,接下來(lái)我們面對(duì)的往往是數(shù)據(jù)結(jié)構(gòu)和算法的學(xué)習(xí)。而現(xiàn)在,我對(duì)于程序的本質(zhì)有了不一樣的答案:分化和組合。我的老師曾經(jīng)告訴我,工程師或者程序員有一個(gè)很重要的能力(我猜這也是最重要的能力),那就是發(fā)現(xiàn)和解決問(wèn)題。而我目前只能接觸到解決問(wèn)題的層次,這也是我也一直在探尋的目標(biāo) —— 分化和組合。
分化與組合在現(xiàn)實(shí)的程序開發(fā)中,我們碰到的問(wèn)題一般是一個(gè)很大的命題,難以抽象,這時(shí)候往往通過(guò)分化子問(wèn)題的方式對(duì)程序進(jìn)行分而治之。在算法里,這種方式叫做分治。
將程序分化成可以抽象的子程序之后,再將他們組合成一個(gè)具有完備功能的程序。組合是程序或代碼可復(fù)用的前提,函數(shù)式編程中組合的使用也會(huì)給我們帶來(lái)意向不到的驚喜
Haskell 的組合Haskell是純函數(shù)式編程語(yǔ)言,他的強(qiáng)大不用我多說(shuō),這里展示一下他的組合能力。
compose :: (b -> c) -> (a -> b) -> a -> c compose f g = f . g
在函數(shù)式編程的組合中,我們是從右到左執(zhí)行的,上述的例子中我們借助 (.) 函數(shù)實(shí)現(xiàn)組合,當(dāng)然,我們也可以用自己的方式實(shí)現(xiàn)。
compose :: (b -> c) -> (a -> b) -> a -> c compose f g x = f (g x)
通過(guò) Haskell 強(qiáng)大的類型簽名中,大致可以推出compose函數(shù)的作用。b -> c 代表了一個(gè)從b類到c類的映射函數(shù),a -> b也是一樣,compose函數(shù)接受兩個(gè)函數(shù)f和g,返回一個(gè)新的函數(shù)h,h函數(shù)表達(dá)了從a類到b類再到c類的映射。
舉個(gè)例子,我們有sum函數(shù) —— 給列表求和,odd函數(shù) —— 判斷數(shù)字是否是奇數(shù)。(簡(jiǎn)單起見,給他們的類型簽名并不準(zhǔn)確,但足夠簡(jiǎn)單)
odd :: Int -> Bool sum :: [Int] -> Int sumIsOdd :: [Int] -> Bool sumIsOdd = compose odd sum sumIsOdd [1,2,34,5]
sumIsOdd函數(shù)組合了求和與判斷奇數(shù)兩個(gè)函數(shù),他并沒(méi)實(shí)現(xiàn)具體的功能,而是通過(guò)一種通俗的組合實(shí)現(xiàn)了將單一的函數(shù)轉(zhuǎn)化成稍微復(fù)雜的函數(shù),從而達(dá)到功能上的擴(kuò)充,我想這就是組合的魅力,也是函數(shù)式的魅力之一吧。
JavaScript 的組合JavaScript是一門表現(xiàn)力極強(qiáng)的語(yǔ)言,除了本質(zhì)上對(duì)面向?qū)ο蟮闹С郑瑢?duì)函數(shù)式編程的支持也絲毫不弱,組合函數(shù)實(shí)現(xiàn)起來(lái)雖然復(fù)雜,但是也未必不可行,而且相對(duì)于Haskell的晦澀,JavaScript更加簡(jiǎn)單一點(diǎn)
const odd = x => x % 2 !== 0; const sum = args => args.reduce((a, b) => a + b); const compose = (...fs) => arg => fs.reduceRight((f, g) => g.call(null, f), arg);
借助ES6的箭頭函數(shù)實(shí)現(xiàn)起來(lái)得心應(yīng)手,可見即便是JavaScript這種以面向?qū)ο笏枷朐O(shè)計(jì)的語(yǔ)言也希望在函數(shù)式編程上面能有所建樹。
順帶一提,對(duì)數(shù)組擴(kuò)充的map、filter、reduce等函數(shù),也是JavaScript對(duì)函數(shù)式編程的支持,雖然只是利用while循環(huán)做的語(yǔ)法糖,效率也不如while循環(huán),但是在JavaScript的語(yǔ)境中,很少對(duì)效率有極高的要求,所以從語(yǔ)義上來(lái)講,我更傾向用函數(shù)式的方式解決純數(shù)據(jù)的問(wèn)題。
小結(jié)函數(shù)式編程隨著多核CPU的發(fā)展,開始再次出現(xiàn)在我們的視野中,有時(shí)候也會(huì)擔(dān)心過(guò)于吹捧函數(shù)式,反而落入俗套。仔細(xì)想想,編程范式并不是一枝獨(dú)秀的世界,而是百家爭(zhēng)鳴的,各有擅長(zhǎng)的領(lǐng)域。當(dāng)然在一些環(huán)境下兩者也是能夠共存的,甚至兩者同時(shí)帶來(lái)的收益可能更加可觀呢。
說(shuō)回組合,其實(shí)我自己也只是一個(gè)半吊子,也需要不斷的學(xué)習(xí)才能對(duì)組合有一個(gè)更加清晰的認(rèn)識(shí),而不是拘泥于語(yǔ)言,在實(shí)際生產(chǎn)中分化和組合也實(shí)在太重要了,并不是一兩個(gè)函數(shù)能夠概括的,現(xiàn)在的也我只能以這種簡(jiǎn)單的方式作了解了。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/97274.html
摘要:函數(shù)式編程逐漸被邊緣化,被拋棄到學(xué)術(shù)界和非主流的場(chǎng)外。組合式編程的重新崛起年左右,有個(gè)巨大的變化爆發(fā)了。人們開始逐漸在私下里談?wù)摵瘮?shù)式編程。箭頭函數(shù)對(duì)于函數(shù)式編程的爆發(fā)起到了推動(dòng)劑的作用。現(xiàn)在很少看到那種不用函數(shù)式編程的大型應(yīng)用了。 showImg(https://segmentfault.com/img/remote/1460000009036867?w=800&h=364); 本...
摘要:組合的概念是非常直觀的,并不是函數(shù)式編程獨(dú)有的,在我們生活中或者前端開發(fā)中處處可見。其實(shí)我們函數(shù)式編程里面的組合也是類似,函數(shù)組合就是一種將已被分解的簡(jiǎn)單任務(wù)組織成復(fù)雜的整體過(guò)程。在函數(shù)式編程的世界中,有這樣一種很流行的編程風(fēng)格。 JavaScript函數(shù)式編程,真香之認(rèn)識(shí)函數(shù)式編程(一) 該系列文章不是針對(duì)前端新手,需要有一定的編程經(jīng)驗(yàn),而且了解 JavaScript 里面作用域,閉...
摘要:函數(shù)組合是函數(shù)式編程中非常重要的思想,它的實(shí)現(xiàn)的思路也沒(méi)有特別復(fù)雜。前者從左向右組合函數(shù),后者方向相反。下面就是一個(gè)最簡(jiǎn)單的可以組合兩個(gè)函數(shù)的在實(shí)際應(yīng)用中,只能組合兩個(gè)函數(shù)的組合函數(shù)顯然不能滿足要求,我們需要可以組合任意個(gè)函數(shù)的組合函數(shù)。 函數(shù)組合是函數(shù)式編程中非常重要的思想,它的實(shí)現(xiàn)的思路也沒(méi)有特別復(fù)雜。有兩種函數(shù)組合的方式,一種是pipe,另一種是compose。前者從左向右組合函...
摘要:函數(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),一...
摘要:可當(dāng)我們進(jìn)行函數(shù)式編程時(shí),這樣的方式會(huì)遇到困難,難點(diǎn)在于如何停止。而在函數(shù)式編程中,數(shù)據(jù)在管道中流動(dòng),上一個(gè)函數(shù)的返回值會(huì)傳給下一個(gè)函數(shù),除非報(bào)錯(cuò),事先寫好的流程是停不下來(lái)的。 以下代碼會(huì)用到函數(shù)組合函數(shù)compose,只要知道compose是干什么的就足夠了,如果好奇具體的實(shí)現(xiàn),可以看《JavaScript函數(shù)式編程之函數(shù)組合函數(shù)compose和pipe的實(shí)現(xiàn)》 在寫命令式的代碼時(shí),...
閱讀 894·2021-09-03 10:42
閱讀 1511·2019-08-30 15:56
閱讀 1444·2019-08-29 17:27
閱讀 870·2019-08-29 15:25
閱讀 3156·2019-08-26 18:27
閱讀 2480·2019-08-26 13:41
閱讀 1888·2019-08-26 10:39
閱讀 1570·2019-08-23 18:36