First Class Function in Java8
自從 Java8 引入函數式程式設計的語法以來,就有一些相關的程式語彙是以前未曾注意到,但是在看函數式程式設計的文章時又常被提起。而一級函數 (First-class Function) 就是其中一個例子.
一等公民 (First-class citizen)
在我們討論一級函數之前,我們先要了解一下另一個名詞一等公民 (First-class citizen)
按照 wiki 的解釋:
wiki : First-class_citizen
In programming language design, a first-class citizen (also type, object, entity, or value) in a given programming language is an entity which supports all the operations generally available to other entities. These operations typically include being passed as an argument, returned from a function, and assigned to a variable.
一個一等公民具有以下主要特徵:
- 可以被當作是參數傳遞.
- 可以被當成回傳值.
- 可以被指派為一個變數.
而一級函數是一等公民的一分子也同樣具有一等公民的特徵,也就是指函數可以被當作參數傳遞,回傳值或指派給一個變數.
以下我們就以 java8 的語法來說明 First Class Function 的一些特性:
高階函數 (High Order Function)
高階函數的定義是函數可以作為參數的傳遞也可以回傳函數當作傳回值.
參數的傳遞
1
2
3Function<Function<Integer,Integer>,Integer> doAt5 = x -> x.apply(5);
doAt5.apply(x -> x + 5 ); // return 8
回傳函數當作傳回值
1
2
3
4
5Function<Double,Function<Double,Double>> generatePow = b -> a -> Math.pow(a,b);
Function<Double, Double> square = generatePow.apply(2.0);
Function<Double, Double> cube = generatePow.apply(3.0);
square.apply(2.0); //return 4
dude.apply(2.0); // return 8
匿名函數 (Anonymous Function/Lambda)
Java 本身就有提供 匿名內部類別(Anonymous inner class), 但在 Java8, 則另外提供 lambda 的語法,使開發者可以用更貼近函數的角度來思考問題.
1
2
3
4
5
6
7
8
9
10// using anonymous class
Runnable runnbale = new Runnable() {
public void run() {
System.out.println("Hi Anonymous Function!");
}
};
// using lambda expressions, after idk 1.8
Runnable runnbale = () -> System.out.println("Hi Anonymous Function!");
柯里化 (Currying)
柯里化是指把一個多參數的函數轉換成一系列的單參數函數。這是一種使用單參數函數去摸擬多參數函數的一種方法.
假設有一個函數為 f (a, b) = a + b, 經過 currying 就可以變成 f (a)(b)
1
2
3
4
5
6
7Function<Integer,Function<Integer,Integer>> add = a -> b -> a + b;
Function<Integer, Integer> plus2 = add.apply(2);
Function<Integer, Integer> plus3 = add.apply(3);
plus2.andThen(plus3).apply(1); // it equals 1+2+3 and returns 6.