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