天天看點

函數式程式設計初探

       最近工作較忙,一直沒更新部落格。不過工作之餘,還是抽時間學習了一點新知識,也就是函數式程式設計方法。函數式程式設計(FP)并不是什麼很新的東西,很久以前,甚至比C語言還早,就已經出現了。最為典型的就是Lisp了。

       本來函數式程式設計并沒有像JAVA那樣成為程式員中的明星,受到的關注也很少。但是随着一些趨勢的發展,人們又再次将目光放在它上面。現在這是一個多核并行的時代,傳統的指令式程式設計存在很多難以克服的問題,最主要的一個就是狀态的可變性,或者說副作用。在函數式程式設計中,你可以聲明一個狀态,但是不能改變這個狀态。而且由于你無法改變它,是以在函數式程式設計中不需要變量。這種特性使得函數式程式設計特别适合于多核計算服務,因為狀态是不可變的,是以我們再也不用提心吊膽擔心資料不一緻和狀态混亂的問題了。

       學習FP最主要的是了解其思想,至于具體的語言上,并沒有必要過分的深究。當然如果大家很有興趣,也可以探究探究。目前在業界存在很多種函數式程式設計語言,個人選擇了Haskell作為入門。一方面haskell是真正的純函數式語言,另一方面,haskell擁有一個良好的開發環境,很容易進行開發測試。當然,haskell文檔較少,主要文檔基本上都是英文,這也是一個問題。

      關于開發環境的搭建,非常容易,大家去google搜尋一下“Haskell

Platform”即可,然後按照自己的系統選擇相應版本下載下傳。一般都是Haskell

Platform For Windows。

      下載下傳後得到一個EXE,然後安裝即可。不得不說,這個還是非常不錯的,沒有任何複雜的配置,也不需要改動什麼配置檔案。

安裝好後從開始菜單進入WinGHCi即可進入Haskell互動式開發環境。

      在函數式程式設計中,遞歸被大量使用。相信很多人和我一樣,以前并不喜歡遞歸,代碼中能避免就避免。一方面遞歸不容易了解,另一方面遞歸對機器的消耗比較嚴重,一不小心就會造成堆棧溢出。但是在FP中,不得不直面遞歸,其實遞歸用多了自然也習慣了,關鍵是思維要轉變過來。

      以著名的斐波那契數列為例:

fib 1 = 1

fib 2 = 1

fib n = fib(n-2)+fib(n-1)

      非常簡潔明了,而且最令人印象深刻的是,函數式程式設計隻要把問題描述清楚了,問題也就解決了。寫這種代碼有種寫數學公式的感覺,非常神奇。

可能這個還是比較容易了解的,下面再來一個乘法的遞歸實作:

mult a 0 s    = s

mult a b s = mult a (b-1) s+a

       這段代碼用的是尾遞歸,比如計算123*321,調用mult  123 

321 0 即可。關于尾遞歸的概念各位若有不清楚可以自行去網上查閱。尾遞歸是一種很安全高效的遞歸,和傳統遞歸不同,尾遞歸隻要優化得當,不會出現堆棧溢出的問題。而且代碼看起來也非常優美,給人一種美感。

再來一個階乘的代碼:

 fac 1 s = s

fac n s = fac (n-1) (n*s)

這個同樣是尾遞歸,優雅而高效。

       對于Haskell的學習,我參看的是久負盛名的Yet

Another Haskell Tutorial。這本小書隻有190多頁,但是基本上把Haskell重要的地方都講到了。如果隻想了解函數式程式設計思想,閱讀前5章就足夠了。另外函數式程式設計的一個核心理論就是“λ演算”,如果沒有學習這個理論作為基礎,則很多東西難以了解。

繼續閱讀