主要來自 Scala 語言發明人 Martin Odersky 教授的 Coursera 課程 《Functional Programming Principles in Scala》。html
好久之前寫過一個很是簡單的 python lambda 函數博客,裏頭有 filter,map,reduce等,是python中頗有意思的部分,能夠先看看。python
另外酷殼網陳皓寫了一篇介紹函數式編程的博客,言簡意賅,對理解函數式編程頗有幫助,很是值得一看。c++
Scala 本意是可伸展。它的設計哲學是:容許用戶經過定義感受像原生語言支持同樣的易用庫去在他們須要的方向上改進和發展語言——Scala allows users to grow and adapt the language in the directions they need by defining easy-to-use libraries that feel like native language support.。Scala 運行在 Java 平臺上,能夠與全部的 Java 庫無縫交互。算法
Scala 是純粹的面向對象式的編程,全部的 value 都是一個對象。
Scala 是函數式的編程,它把每個函數看作一個 value,函數即對象。shell
純函數(Pure Function)是這樣一種函數——輸入輸出數據流全是顯式(Explicit)的。 編程
顯式(Explicit)的意思是,函數與外界交換數據只有一個惟一渠道——參數和返回值;函數從函數外部接受的全部輸入信息都經過參數傳遞到該函數內部;函數輸出到函數外部的全部信息都經過返回值傳遞到該函數外部。 緩存
隱式(Implicit)的意思是,函數經過參數和返回值之外的渠道,和外界進行數據交換。好比,讀取全局變量,修改全局變量,都叫做以隱式的方式和外界進行數據交換;好比,利用I/O API(輸入輸出系統函數庫)讀取配置文件,或者輸出到文件,打印到屏幕,都叫作隱式的方式和外界進行數據交換。 安全
Pure Function的好處主要有幾點: session
在函數式編程語言裏面,函數是一等公民,這意味着:
scala 函數定義格式以下:
def fun(x:Int, y: => Int) = ...
中的 =>
顯式調用。關鍵字 def 也是這種模式舉個例子:
def loop: Int = loop // 定義一個死循環,def 能夠,val 不行 def constOne(x: Int, y: => Int) = 1 // 第一個參數x: call by value, 第二個參數y: call by name constOne(1+2, loop) // loop一直沒用,因此沒有計算,輸出1 constOne(loop, 1+2) // 遇到loop當即計算,陷入死循環
牛頓法的基本思路是遞歸,首先猜想爲 1.0,若是偏差過大,則猜想值改成 guess 與 x / guess 的平均值。
object session { def abs(x: Double) = if (x>=0) x else (-x) def sqrt(x: Double) = { def sqrtIter(guess: Double): Double = if (isGoodEnough(guess)) guess else sqrtIter(improve(guess)) def isGoodEnough(guess: Double) = abs(guess * guess - x) / x < 0.001 def improve(guess: Double) = (guess + x / guess) / 2 sqrtIter(1.0) } sqrt(2.0) }
這篇博客推薦看看——遞歸與尾遞歸總結。
遞歸相對經常使用的算法如普通循環等,運行效率較低。在遞歸調用的過程中系統爲每一層的返回點、局部量等開闢了棧來存儲,所以遞歸次數過多容易形成棧溢出。
尾遞歸對應 imperative program(如c++)中的循環。 函數調用出如今調用者函數的尾部, 由於是尾部, 因此根本沒有必要去保存任何局部變量(須要保存的變量能夠放在函數參數列表裏)。它的棧是常數,可複用,與循環同樣高效。
遞歸:
// 階乘函數 def factorial(n: Int): Int = if (n == 0) 1 else n * factotial(n - 1)
尾遞歸:
// 階乘函數 def factorial(n: Int) = { def loop(acc: Int, n: Int): Int= if (n == 0) acc else loop(acc * n, n - 1) loop(1, n) }