2010-01-04 108 views
3

我試圖定義類型:ocaml記錄類型和null

type aaa = NULL | {a:int; b:int} ;;

但編譯器不允許這樣做。我不確定爲什麼我們不能將記錄類型與其他任何東西混合。

我需要匹配一個值,如果它是記錄類型或空記錄,我厭倦了創建像{a = -999; b = -999}。

有沒有更好的方法?

回答

7

定義的「記錄」部分必須以單獨的類型完成。然後,如果要表達「無」或「某些值」,則可以將其包裝在「選項」類型中。

type aaa = {a: int; b: int} 
type bbb = aaa option 
7

第一個問題:在Objective Caml方法中,不能有沒有構造函數的乾淨的聯合類型。考慮以下難題:

type test = Null | {a : int ; b: int } 

let value = { a: 0 ; b : 42 } in print_int value.a 

第二行是不正確的,因爲value是聯合類型的,並且因此可能是Null,它沒有構件a。這會引入關於聯盟類型價值的隱含假設,Objective Caml不惜一切代價避免。這意味着你需要一個構造函數。

但即使這樣,就足夠了,因爲這樣你就會有一個匿名的記錄類型:

type test = Null | Pair of { a : int ; b : int } 

match Pair { a : 0 ; b : 42 } with 
    | Null -> 0 
    | Pair p -> p.a 

會是什麼p這裏的類型?這當然可以通過將匿名記錄類型應用到語言中來解決,但這不是一個簡單的補充,因爲這類類型通常很難用類型統一方法處理,並且需要大量額外的支持結構(例如,< ; ... >#typevalue :> type構造用於處理對象)。

語言設計師採取了簡單的方法,並要求所有記錄類型都接收一個名稱。當然,如果你有一個非常簡單的記錄,你可以使用一個元組:

type test = Null | Pair of int * int 
+0

輝煌的答案,統一很是頭疼,我不能得到它背後的全貌尚未 – 0xFF 2010-01-04 22:22:13