Dot-Net

什麼是行類型?它們是代數數據類型嗎?

  • January 4, 2018

我經常聽到 F# 缺乏對 OCaml 行類型的支持,這使得該語言比 F# 更強大。

這些是什麼?它們是代數數據類型,例如求和類型(可區分聯合)還是乘積類型(元組、記錄)?是否可以用其他方言(例如 F#)編寫行類型?

首先,我們需要修正術語。至少在類型理論中,尤其是在 OCaml 的類型系統中,沒有“行類型” †這樣的東西。存在“行多態性”,我們將在下面討論它0。

行多態是多態的一種形式。OCaml 提供了兩種多態性——參數和行,而缺少另外兩種——即席和包含(又名子類型)1。

首先,什麼是多態性?在類型系統的上下文中,多態性允許單個術語具有多種類型。這裡的問題是單詞類型本身在電腦科學和程式語言社區中嚴重超載。所以為了盡量減少混淆,讓我們在這裡重新介紹一下,放在同一頁上2。術語的類型通常表示術語語義的某種近似。語義可以像一組帶有一組操作或更複雜的值(如效果、註釋和任意理論)一樣簡單。通常,語義表示一個術語的所有可能行為的集合。類型系統‡表示一組規則,允許某些語言構造並根據其類型禁止其他語言構造。即,它驗證術語的組合是否正確執行。例如,如果在一種語言中有一個函式應用程序構造,則類型系統將只允許對那些類型與參數類型匹配的參數應用程序。這就是多態性發揮作用的地方。在單態類型系統中,這種匹配只能是一對一的,即文字。多態類型系統提供了一些機制來指定一些與一系列類型匹配的正則表達式。因此,不同種類的多態性只是不同種類的正則表達式,您可以使用它們來表示類型族。

現在讓我們從這個角度來看看不同種類的多態性。例如,參數多態性就像正則表達式中的一個點。例如,'a listis . list- 這意味著我們按字面意思匹配,list並且類型的參數list可以是任何類型。行多態性是星號運算符,例如,<quacks : unit; ..>與 相同<quacks : unit; .*>。這意味著它與任何類型匹配quacks並執行其他任何操作3。說到名義子類型,在這種情況下,我們有名義類(也稱為正則表達式中的字元類),並且我們用它們的基類的名稱來指定一個類型族。例如,duck就像[:duck:]*任何正確註冊的值作為類的成員與此類型匹配(通過類繼承和新運算符)4。最後,ad-hoc 多態性實際上也是名義上的並且映射到正則表達式中的字元類。這裡的主要區別在於,即席多態中的類型概念不是應用於值,而是應用於名稱。因此,一個名稱,如函式名或+運算符,可能有多個定義(實現),應該使用某種語言機制靜態註冊(例如,重載運算符、實現方法等)。因此,ad-hoc 多態性只是名義子類型的一個特例。

現在,當我們清楚時,我們可以討論行多態性給我們帶來了什麼。與提供子類型多態性的名義類型系統相比,行多態性是結構類型系統(在動態類型語言中也稱為鴨子類型)的一個特徵。一般來說,正如我們上面所討論的,它允許我們將類型指定為“任何嘎嘎的東西”,而不是“任何實現 IDuck 介面的東西”。所以是的,你當然可以通過定義鴨子介面並使用一些inheritimplements機制。但是這裡的主要問題是您的層次結構是密封的,即您需要更改程式碼以在新創建的介面中註冊實現。這打破了開放/封閉原則並阻礙了程式碼重用。名義子類型化的另一個問題是,除非您的層次結構形成一個格子(即,對於任何兩個類,總是有一個最小上限),否則您無法在其上實現類型推斷5。

延伸閱讀


0)正如@nekketsuuu 在評論中指出的那樣,我使用的術語有點自願,因為我的目的是提供一個易於理解和高級別的想法,而不是深入細節。從那以後,我修改了文章,使其更加嚴格。

1)然而,OCaml 為類提供了繼承和子類型的概念,根據通用定義,它仍然不是子類型多態性,因為它不是名義上的。從其餘的答案中應該會更清楚。

2)我只是在修正術語,我並沒有聲稱我的定義是正確的。許多人認為類型表示值的表示,從歷史上看這是正確的。

3)也許一個更好的正則表達式會,<.*; quacks : unit; .*>但我認為你明白了。

4)因此OCaml沒有子類型多態性,儘管它有子類型的概念。當您指定一個與子類型不匹配的類型時,它只會按字面意思匹配,並且您需要使用顯式向上轉換運算符來使類型 T 的值適用於super(T)預期的上下文。因此,儘管 OCaml 中有子類型,但它與多態性無關。

5)雖然格的要求看起來不是不可能的,但在現實生活中很難對層次結構施加這種限制,或者如果施加這種限制,類型推斷的精度將始終與類型層次結構的精度綁定。所以在實踐中,它不起作用,cf。斯卡拉

†(第一次閱讀時跳過此註釋)儘管在 OCaml 中存在用於將行多態性嵌入到僅具有參數多態性的 OCaml 類型推斷中的行變數。

‡)通常,類型一詞可與類型系統互換使用,以指代整個類型系統中的一組特定規則。例如,有時我們說“OCaml 具有行類型”來表示這樣一個事實,即 OCaml 類型系統為“行多態性”提供了規則。

引用自:https://stackoverflow.com/questions/48092739