既存型別(Existential Type)

已存在型別(Existential Type)


Existential類型


Bill Venners:最近Scala中添加了一些Existential(存在)類型。我聽說添加Existential類型的理由是為了可以映射所有 Java類型到Scala類型,特別是Java的通配符類型。Existential類型數量是否多於Java通配符類型?它們是否是Java通配符類型 的一個擴展集?是否存在其他人們應該瞭解它的理由? 

Martin Odersky:這很難說,因為人們並沒有一個真正的關於什麼是通配符概念。最初由Atsushi Igarashi和Mirko Viroli設計的通配符,其靈感來源於Existential類型。事實上,最初的論文中存在一個使用Existential類型的編碼。但後來當實際 最終設計在Java中實現時,這種聯繫就減少了一些。所以,現在我們真的不瞭解這些通配符類型的狀況。

Existential類型已經出現許多年了,至今為止大約有20年左右。這種類型可以很簡單地表達信息。例如你有一個類型,也許是list(列 表)類型,其中一個列表項的類型你不知道,你只知道它是一些特殊元素類型的列表,但你不知道元素的類型。在Scala中,這就可以表示成一個 Existential類型。語法是List[T] forSome { type T }.。這看起來有點繁瑣。這種繁瑣的語法實際上是故意的,因為它產生的Existential類型通常有點難以處理。現在,Scala有了更好的選擇。它 並不需要這麼多Existential類型,因為我們可以使用包含其他類型成員的類型。 

Scala需要Existential類型有3個本質上的理由。首先,我們需要弄清一些Java通配符的意 思,Existential類型就是我們所理解的意思。其次,我們需要弄清一些Java raw(原始)類型的意思,因為它們仍處於類庫中,是ungenerified(非屬性的)類型。如果你使用一個Java原始類型,如 java.util.List,這是一個列表,你不知道列表元素的類型。在Scala中這可以被表示成一個Existential類型。最後,我們需要使 用Existential類型來解釋在虛擬機上發生著什麼事情。Scala像Java一樣,使用泛型擦除模式,所以當程序運行時,我們不再能看到類型參 數。為了能與Java互用,我們需要進行擦除操作。但是,當我們做映射或想要表示時,在虛擬機上會發生什麼事情?我們需要能夠表達虛擬機在使用Scala 中的類型時做了什麼事情,Existential類型讓我們做到了這一點。Existential類型可以讓你在不瞭解類型中某些方面的情況下使用它們。

Bill Venners:您能舉一個具體的例子嗎? 

Martin Odersky:以Scala lists(列表)為例。我希望能夠描述方法的返回類型,head,它會返回列表第一個元素(頭一個)。在VM水平,這是一個List[T] forSome { type T }。我們不知道T是什麼。Existential類型理論告訴我們,這是一個適合某個類型T的T。這相當於根類型——對象。因此,我們從head方法得到 這個類型。因此在Scala中,當我們知道某個類型時,我們可以消除這些Existential限制。當我們不知道某個類型時,我們就可以使用 Existential,Existential類型理論就是在這裡給予我們幫助。 

Bill Venners:如果您沒有必要擔心與Java通配符、原始類型和擦除的兼容性,還會添加Existential類型嗎?如果Java擁有具體化的類型,沒有原始類型和通配符,那麼Scala還會有Existential類型嗎? 

Martin Odersky:如果Java擁有具體化的類型,沒有原始類型和通配符,我認為Existential類型的使用量就沒那麼大了,那麼我會考慮Scala不使用它。


Comments