深入淺出 F# 之 Partial Function Application
更優雅的方式產生 function
FP 既然強調 Higher Order Function,就會希望 argument 以 function 傳入,因此就會有 function 能夠傳回 function 的需求,除了回傳 Anonymous Function 或 Lambda Expression 外,F# 更提供了 Partial Function Application ,讓程式碼更優雅。
Version
macOS High Sierra 10.13.3
.NET Core SDK 2.1.101
Rider 2017.3.1
F# 4.1
Lambda Expression
舉一個最簡單的例子
1 | [1..5] |
將 1
到 5
的 List
全部印出來。
List.iter()
的 argument 要求 'T -> unit
的 function。
在沒有提供 Partial Function Application 的程式語言,我們會傳進 Anonymous function 或 Lambda Expression。
1 | fun i -> printfn "%d" i |
這種寫法中規中矩,儘管語法不太一樣,在一般語言都看得到。
Partial Function Application
1 | [1..5] |
既然 List.iter()
的 argument 要求 'T -> unit
的 function,我們只要能產生 T -> unit
就符合 List.iter()
的需求。
printfn()
的 singnature 為 string -> 'T -> unit
,他的意思是:
- 當傳入兩個參數為
string
與'T
時,回傳值為unit
- 當傳入一個 參數為
string
時,回傳值回T -> unit
List.iter()
要的正是 'T -> unit
,所以我們只要傳入一個參數即可。
1 | printfn "%d" |
這種寫法是不是比 Lambda Expression 更優雅呢?
Summary
- 在多參數的 function,只要提供
部分參數
,就會回傳一個新的 function,而不必自己建立 Anonymous Function 或 Lambda Expression。 - 在多參數的 function,其型別是以
->
隔開,如string -> 'T -> unit
,而不是string, 'T -> unit
,因為 F# 的 function 可隨時提供部分參數
,而回傳新的 function,如只提供string
,就會回傳'T -> unit
,這也是為什麼 F# 在每個參數間以->
隔開,而非,
Conclusion
- Partial Function Application 並不是 F# 的獨門絕技,只要是 FP 語言都會有,算是 FP 語言的基本要求,但在一般語言如 C#、JavaScript 卻看不到,只能使用 Lambda Expression / Anonymous Function / Arrow Function 來處理,但 Partial Function Application 提供了更優雅的方式