Scala 3 — 書籍

函數是值

語言

儘管每個程式語言都允許您撰寫純函數,但另一個重要的 Scala FP 功能是您可以將函數建立為值,就像您建立 StringInt 值一樣。

此功能有許多好處,最常見的有:(a) 您可以定義方法來接受函式參數,以及 (b) 您可以將函式作為參數傳遞至方法中。您已在本書的許多地方看過這一點,只要示範了 mapfilter 等方法時

val nums = (1 to 10).toList

val doubles = nums.map(_ * 2)           // double each value
val lessThanFive = nums.filter(_ < 5)   // List(1,2,3,4)

在那些範例中,匿名函式會傳遞至 mapfilter

匿名函式也稱為lambda

除了將匿名函式傳遞至 filtermap 之外,您也可以提供方法

// two methods
def double(i: Int): Int = i * 2
def underFive(i: Int): Boolean = i < 5

// pass those methods into filter and map
val doubles = nums.filter(underFive).map(double)

將方法和函式視為值的這項功能是函式式程式語言提供的強大功能。

技術上來說,將另一個函式視為輸入參數的函式稱為高階函式。(如果您喜歡幽默,就像某人曾經寫的,這就像說將另一個類別的執行個體視為建構函式參數的類別是高階類別。)

函式、匿名函式和方法

正如您在那些範例中看到的,這是一個匿名函式

_ * 2

高階函式 討論中所示,這是此語法的簡寫版本

(i: Int) => i * 2

像這樣的函式稱為「匿名」,因為它們沒有名稱。如果您想為其命名,只需將其指定給變數即可

val double = (i: Int) => i * 2

現在您有一個已命名函式,一個指定給變數的函式。您可以像使用一個方法一樣使用此函式

double(2)   // 4

在大部分情況下,double 是函式或方法並無差別;Scala 讓你可以用相同的方式處理它們。在背後,Scala 技術讓你將方法視為函式處理,稱為 Eta 展開

這種將函式作為變數無縫傳遞的能力是像 Scala 這類函式程式語言的顯著特徵。正如你在本書中 mapfilter 範例中所見,將函式傳遞到其他函式中的能力有助於你建立簡潔且可讀的程式碼,也就是具表現力的程式碼。

如果你不熟悉將函式作為參數傳遞到其他函式的過程,這裡有幾個你可以實驗的範例

List("bob", "joe").map(_.toUpperCase)   // List(BOB, JOE)
List("bob", "joe").map(_.capitalize)    // List(Bob, Joe)
List("plum", "banana").map(_.length)    // List(4, 6)

val fruits = List("apple", "pear")
fruits.map(_.toUpperCase)       // List(APPLE, PEAR)
fruits.flatMap(_.toUpperCase)   // List(A, P, P, L, E, P, E, A, R)

val nums = List(5, 1, 3, 11, 7)
nums.map(_ * 2)         // List(10, 2, 6, 22, 14)
nums.filter(_ > 3)      // List(5, 11, 7)
nums.takeWhile(_ < 6)   // List(5, 1, 3)
nums.sortWith(_ < _)    // List(1, 3, 5, 7, 11)
nums.sortWith(_ > _)    // List(11, 7, 5, 3, 1)

nums.takeWhile(_ < 6).sortWith(_ < _)   // List(1, 3, 5)

此頁面的貢獻者