1. 程式人生 > >Scala類型系統——高級類類型(higher-kinded types)

Scala類型系統——高級類類型(higher-kinded types)

response 結果 shu scala集合 back upload cat AS 簡單

高級類類型就是使用其他類型構造成為一個新的類型,因此也稱為 類型構造器(type constructors)。它的語法和高階函數(higher-order functions)相似,高階函數就是將其它函數作為參數的函數;高級類類型則是將構造類類型作為參數類型。一個高級類類型可以有一個或者多個類型作為參數。在Scala中,你可以使用type關鍵字聲明,如下:

這裏定義了一個高級類類型Callback,該類型接收一個類型 T,並構造一個新的類型Function1。類型Callback不是一個完整的類型,直到它實現了參數化。

Function0,Function1,... 表示接收類型個數1,2,3,... ,如Function0[A],Function1[A,B]... ,一共23個FunctionX。用於定義匿名語法,實現語法糖。

高級類類型可以用於創建復雜類型,如M[N[T,X],Y],但可以看作更簡單的類型,F[X]。

Higher-kinded types

除了上面說的用關鍵字type定義的類型外,高級類類型最常見的實現是使用占位符代替。即F[_],在Scala中,占位符 _ 有特別的意義,可以表示任何東西。

User Story

如我們要實現一個sum方法,該方法可以接收任何Scala集合類型,並實現加法處理。我們可能實現的一種方式是,為所有集合類型定義相對應的方法:

但這並不是一個高效的函數實現,我們要對所有集合類型進行抽象,以使得sum方法可以接收任何集合類型。因此,我們要實現高級類類型。

現在,我們分別為不同的類型實現該特質:

現在,我們要為這個抽象的類類型,實現抽象的方法:

它接收所有集合類型,現在我們為其實現具體的實現:

根據這個特質,我們現在可以實現其通用的函數sum,該函數接收三個參數:集合、Foldable特質、Summable特質,如下:

執行這個方法,打印輸出:

好了,我們的高級類類型就已經實現了。但是等等,上面這個函數看起來很死板,我為什麽要接收三個參數呢,有沒有sum(List(1,2,,3)) sum(Array("one", "two", "three"))這樣的實現?有!

Scala有個強大的特性就是隱式調用,我們需要實現這個sum函數的隱式調用,修改如下:

上面的寫法實際上和下面是同價的:

修改上述sum函數,讓其只接收一個參數:

SBT控制臺執行上述代碼,便可以得到相同的結果。 技術分享圖片

Scala的高級類類型很有用,並且用途廣泛,下面我們看看一個Java Servlet到Scala Servlet的一個轉換框架Scalaz。

Scalaz核心實現

Scalaz的核心部分很簡單,該框架的核心就是實現了所有HTTP請求和響應的抽象。即,把所有的HTTP請求抽象為一個Request特質,所有響應也抽象為一個Response特質。我們看看這個抽象實現的核心代碼:

沒錯,這裏的Application,對應Java Servlet裏面的application,其中IN[]和OUT[]的實現為Request[IN] => Response[OUT],即抽象請求處理後,返回抽象響應。這個方法實現了高級類類型(higher-kinded types),該方法實現了輸入到輸出的所有轉換,這裏的f函數為一個高階函數實現。

通過高級類類型,結合高階函數,函數組合,並結合相應的隱式轉換和語法糖,Scalaz框架便由此誕生了!!

https://my.oschina.net/Barudisshu/blog/690595

Scala類型系統——高級類類型(higher-kinded types)