2011-06-01 51 views
8

我有一門功課練習OCaml中做參數的類型......陣列與OCaml中

我的老師說,我們必須使用這2種類型:

type 'a zapis = Prazen | Zapis of string * 'a;; 
type 'a asocpolje = 'a zapis array;; 

我的問題是,當我創建一個數組:

# let a = Array.make 5 Prazen;; 
val a : '_a zapis array = [|Prazen; Prazen; Prazen; Prazen; Prazen|] 

我不知道是什麼值可以在此數組中插入...

a.(0)<-??? 

有人可以告訴我哪個值可以插入到這個數組中嗎?

回答

11

在向陣列添加任何內容之前,類型未完全定義。如果你仔細觀察,你會看到'a你給類型參數已成爲'_a(注意_

val a : '_a zapis array = [|Prazen; Prazen; Prazen; Prazen; Prazen|]

:這反映在array所指定的類型。這種類型意味着「某種類型,但我不知道哪一種」。與'a相反,這意味着任何類型。

這意味着在這一點上你可以插入任何種類的Zapis。一旦你這樣做了,你只能插入那種特殊類型的Zapis(在其他類型中,'_a會消失並被替換爲正確的類型)。

所以,如果你

a.(0) <- Zapis ("z", 10) 

a將成爲從那一刻int zapis array和只接受整數。

如果你這樣做,而不是

a.(0) <- Zapis ("z","z") 

它會成爲一個string zapis array只接受字符串之後。

+0

感謝這個...我真的需要它:) – Cevap 2011-06-01 09:43:20

+0

你能告訴我如何創建一個數組類型asocpolje? – Cevap 2011-06-01 09:44:01

5

你能告訴我如何創建一個數組類型asocpolje嗎?

'a asocpolje'a zapis array相同類型。根據typer推斷你的定義的方式,你會得到一個或另一個,但它們完全相同。 'a asocpolje只是別名對於'a zapis array,不是一種新的類型。

可以幫助OCaml的使用顯式類型批註打印正確類型的信息:

let t : 'a asocpolje = Array.make ... 

我會然而勸阻這種做法。它的行爲方式並不明顯(例如,'a的含義可能會令人驚訝,它不會強制實現多態),並且您確實試圖在沒有(類型相同)的地方發揮作用。如果你真的這兩種類型的區別,你應該定義'a asocpolje作爲一種新的代數類型(只有一個的情況下):

type 'a zapis = Prazen | Zapis of string * 'a;; 
type 'a asocpolje = Asocpolje of 'a zapis array;; 

let t = Asocpolje (Array.make ...) 
let get (Asocpolje t) n = t.(n)