19

聯合類型和交集類型的各種用例是什麼?最近關於這些類型的系統功能引起了很多關注,但我從來沒有覺得需要這些功能!聯合類型和交集類型

+1

當你說「聯盟類型」,你的意思是「不交/總和」,如ML代數數據類型,或者未標記的工會與在C'union'? – gasche 2011-04-13 18:46:47

+0

@gasche:粗略的類型。 – missingfaktor 2011-04-13 18:48:33

+1

您是否在尋找示例?這是一個非常廣泛的問題。這就像問,產品類型的用例是什麼,或者(也許你更熟悉的)C'struct'。我不知道從哪裏開始。 – 2011-04-13 18:57:35

回答

9

如果你想要一個更注重實踐的答案:

隨着工會和遞歸類型,您可以編碼則樹類型,因此XML類型。

有了交集類型,您可以輸入兩個重載函數和細化類型(在以前的文章中所謂的相干超載)

因此,例如,你可以寫的函數add(即重載整數之和字符串連接)作爲如下

let add ((Int,Int)->Int ; (String,String)->String) 
     | (x & Int, y & Int) -> x+y 
     | (x & String, y & String) -> [email protected] ;; 

其具有交叉點型

(INT,INT) - >內部&(字符串,字符串) - >字符串

但你也可以細化上述類型並輸入上面

(Pos,Pos) -> Pos & 
(Neg,Neg) -> Neg & 
(Int,Int)->Int & 
(String,String)->String. 

若pos和NEG正負整數類型的功能。

上述代碼可以使用語言CDuce(http://www.cduce.org)執行,其類型系統包括聯合,交集和否定類型(主要針對XML轉換)。

如果你想嘗試它,你在Linux上,那麼它可能包含在你的發行版中(apt-get install cduce或yum install cduce應該完成這項工作),並且你可以使用它的頂層(a la OCaml)玩聯合和交叉點類型。在CDuce網站上,您會發現許多使用聯合和交叉點類型的實際示例。由於與OCaml庫完全集成(您可以在CDuce中導入OCaml庫並將CDuce模塊導出到OCaml),您還可以檢查ML總和類型的對應關係(請參閱here)。

在這裏,你是一個複雜的例子,混合並和交類型(在網頁「http://www.cduce.org/tutorial_overloading.html#val」解釋),而是要了解它,你需要了解的正則表達式模式匹配,這需要一些努力。

type Person = FPerson | MPerson 
type FPerson = <person gender = "F">[ Name Children ] 
type MPerson = <person gender = "M">[ Name Children ] 
type Children = <children>[ Person* ] 
type Name  = <name>[ PCDATA ] 

type Man = <man name=String>[ Sons Daughters ] 
type Woman = <woman name=String>[ Sons Daughters ] 
type Sons = <sons>[ Man* ] 
type Daughters = <daughters>[ Woman* ] 

let fun split (MPerson -> Man ; FPerson -> Woman) 
    <person gender=g>[ <name>n <children>[(mc::MPerson | fc::FPerson)*] ] -> 
    (* the above pattern collects all the MPerson in mc, and all the FPerson in fc *) 
    let tag = match g with "F" -> `woman | "M" -> `man in 
    let s = map mc with x -> split x in 
    let d = map fc with x -> split x in  
    <(tag) name=n>[ <sons>s <daughters>d ] ;; 

在它轉換Person類型的值轉換成類型的值簡而言之(曼|女性)(其中垂直條表示聯合類型),但保持類型之間的對應關係:分割與交叉點型

函數
MPerson -> Man & FPerson -> Woman 
21

聯盟類型

引述羅伯特·哈珀,「爲編程 現實基礎語言」,15章:

大多數數據結構包括 替代品,如葉之間的區別 一棵樹的內部節點,或者一個抽象語法的最外層 形式的選擇。 重要的是,這個選擇決定了該值的 結構。例如, 節點有子節點,但樹葉節點不是 ,等等。這些概念 由和類型,具體來說 二進制和,它提供了一個選擇的兩件事情 ,以及零元和, 它提供的東西沒有選擇表示。

布爾

最簡單的總和類型是布爾,

data Bool = True 
      | False 

布爾只有兩個有效值,T或F.因此,而不是代表他們的數據,我們可以改爲使用和類型更準確地編碼事實只有兩個可能的值。

枚舉

枚舉是更一般的總和類型的例子:那些有許多,但有限的,可替代的值。

總和類型和空指針

的最佳實踐激勵例如用於和類型,是由函數返回,通過區分故障情況下有效結果和錯誤值之間進行區分。

例如,空指針和結束文件字符是總和類型的hackish編碼:

data Maybe a = Nothing 
      | Just a 

在這裏我們可以通過使用NothingJust標籤來註釋每一個有效和無效值之間區分價值與地位。

通過以這種方式使用求和類型,我們可以完全排除空指針錯誤,這是一個非常體面的激勵示例。空指針完全是由於舊語言無法容易地表達和類型。

交會類型

路口的類型是非常新的,和他們的應用程序沒有被廣泛理解。然而,本傑明·皮爾斯的論文(「有交集類型 和有界多態性編程」)給出了一個很好的概述:

最有趣的和潛在的交集類型 的 有用的特性是它們表達的 基本無界(的能力盡管 課程有限)關於程序組件的信息量 。

對於 例如,除了功能(+)可以 給出的類型Int -> Int -> Int^Real -> Real -> Real,捕捉無論是 一般的事實,兩個實 數之和始終是一個真正的和更 專門的事實,兩個 總和整數總是一個整數。甲 編譯器語言與 相交類型甚至可能提供 兩個不同的對象的代碼序列 用於(+),一個在兩個版本使用 FL浮點加法指令和 一個使用整數加法。對於程序中+的每個 實例, 編譯器可以決定參數是否爲整數,並在此情況下生成更有效的目標代碼序列 。

這種網絡nitary 多態性或連貫超載 是如此的表現,那...一組的 所有有效分型的程序 達一個完整的鑑定程序的行爲

他們讓我們編碼許多類型的信息,通過類型理論解釋多重繼承的含義,給出類型類型,

+1

總和類型不是聯合類型。請參見[http://www.cs.cmu.edu/~joshuad/papers/intcomp/]以獲得聯合和交叉點類型的完整處理。 – naasking 2015-02-25 17:30:48

+1

鏈接已死,請嘗試:http://www.mpi-sws.org/~joshua/ - 如果有進一步的鏈接,作者的名字是Joshua Dunfield – 2015-06-13 23:54:11

11

聯盟類型是這對輸入動態語言非常有用,或者在大多數靜態語言允許的類型中允許更多的傳遞類型的靈活性例如,考慮一下:

var a; 
if (condition) { 
    a = "string"; 
} else { 
    a = 123; 
} 

如果有工會的類型,很容易爲int | string鍵入a

交叉點類型的一個用途是描述一個實現多個接口的對象。例如,C#允許多個interface constraints仿製藥:

interface IFoo { 
    void Foo(); 
} 

interface IBar { 
    void Bar(); 
} 

void Method<T>(T arg) where T : IFoo, IBar { 
    arg.Foo(); 
    arg.Bar(); 
} 

這裏,arg的類型是IFooIBar的交叉點。使用它,類型檢查器知道都是Foo()Bar()是它的有效方法。

-1

例如與工會類型的人能描述JSON域模型沒有引入實際的新類,但只使用類型別名。

type JObject = Map[String, JValue] 
type JArray = List[JValue] 
type JValue = String | Number | Bool | Null | JObject | JArray 
type Json = JObject | JArray 

def stringify(json: JValue): String = json match { 
    case String | Number | Bool | Null => json.toString() 
    case JObject => "{" + json.map(x y => x + ": " + stringify(y)).mkStr(", ") + "}" 
    case JArray => "[" + json.map(stringify).mkStr(", ") + "]" 
} 
+5

沒有任何解釋的代碼唯一答案不是很很有幫助。 – 2015-01-16 14:27:40

+1

請提供一些解釋,以提高您的答案的質量。請參閱此處以獲取[寫作答案](http://stackoverflow.com/help/how-to-answer)上的幫助。 – jacefarm 2016-12-14 07:38:08