01.函數值(Function Values)

Function Values

方法行為(Method)不俱副作用是函數編程風格程序的一個很重要的理念。Method 唯一的效果應該是計算並返回值。用這種方式工作的好處就是在方法之間很少糾纏在一起,因此程序也就更加可靠和可重用性。

將函數(Functional)作為 Scala 一級概念的最主要含義是,它們必須被識別為單獨的程序結構,也可稱為閉包(Closures). Scala 內部能達到高階函數的功能, 所有的函數都被創建為特殊類型的實例, 故 Scala 的函數值是真正的物件.


DRY(Don't Repeat Yourself)


把實作包在一個函數裡
Scala 可以將函數值並在任意處使用它



無副作用函數


fish: Int => Int, 單純的輸入轉為輸出

scala> def fish = (x: Int) => Int
fish: (Int) => Int.type

scala> val fish = (x: Int) => Int
fish: (Int) => Int.type = <function1>

scala> var fish = (x: Int) => Int
fish: (Int) => Int.type = <function1>

scala> def totalResultOverRange1(number: Int, codeBlock: (Int) => Int ): Int = {

     | var result = 0                                                           

     | for ( i <- 1 to number) {                                                

     | result += codeBlock(i)

     | }

     | result

     | }

totalResultOverRange1: (number: Int,codeBlock: (Int) => Int)Int





匿名即時(Just In Time)函數


不指定名稱只有實作的函數


scala> totalResultOverRange1(10, t => t)
res3: Int = 55

scala> totalResultOverRange1(10, t => if (t % 2 == 0) t else 0)
res4: Int = 30


scala> def fish(kuo: Int => Int) = { kuo }
fish: (kuo: (Int) => Int)(Int) => Int

scala> def fish = (kuo: Int) => Int       
fish: (Int) => Int.type







從例子中學起


在 Scala 中函數的設計結構沒有想像中的複雜, 在這 Scala 是要告訢你當你在撰寫 Scala 程序同時, 在許多地方你早已不自覺正使用著 FP(函數語言) 帶來的優點, 下列最抽象的表達式及簡易範例,


(命名參數列表) => 函數內容

變性 函數名稱 = (參數...) => 函數式內容...

Ex.
scala> val Fish = (age: Int) => "age: " + age
Fish: (Int) => java.lang.String = <function1>

scala> Fish(2)
res0: java.lang.String = age: 2





Example - Eclipse







通配符 '_' 的應用


scala> List(1, 2, 3, 4).map { _ * 2 }
res1: List[Int] = List(2, 4, 6, 8)

scala> List(1, 2, 3, 4) map { _ * 2 }
res2: List[Int] = List(2, 4, 6, 8)

scala> List(1, 2, 3, 4) map(_ * 2)  
res3: List[Int] = List(2, 4, 6, 8)




Closures


記得老魚第一次了解閉包是從學習 Groovy 過程中理解的, 許多全球 Java 開發者都在正負面討論 Closures 是不是該加到下一代的 Java 新版本之中, 使用 Closures 可以用來替代難懂的 Java Inner classes(內部類別), 也大副降低學習與使用 Java 門檻, 但面對已有 15 年的老語言, 為了向下相容性, 許多決議都很難被取捨 ...



Functions


函數語言的名稱源於這樣一種概念:程序行為應該像數學函數一樣;換句話說,給定一組輸入,函數應始終返回相同的輸出。這不僅意味著每個函數必須返回一個 值,還意味著從一個調用到下一個調用,函數本質上不得具有內蘊狀態(intrinsic state)。這種無狀態的內蘊概念(在函數/對象領域中,默認情況下指的是永遠不變的對象),是函數語言被認為是並發領域偉大的 「救世主」 的主要原因。

函數語言 — Haskell、ML 或函數領域的新成員 F#



References





子網頁 (1): 深入函數
Comments