2013-04-01 72 views
1

我一直想弄清楚如何在OCaml中調用調整大小已經初始化的數組。然而,看起來雖然你可以編寫一個函數來創建一個全新的數組,並且複製了舊數組的元素(和額外的插槽),但是該函數的輸出不能分配給現有的數組。如何做到這一點?有沒有一種簡單的方法可以使用引用來做到這一點,如果不是沒有?OCaml:動態數組?

這裏有一個小例子:

 
let rec function_that_adds_to_array storage args ... = 
    (* let's say the function has a set of if-else constructs that controls what it does, and let's further say that one of the cases leads to: *) 
    let new_array = Array.make (Array.length storage) ("Null", ("Null", -2)) in 
    Array.blit collection 0 new_array 0 index; (* index is controlled by the function's recursion *) 
    Array.set new_array index (obj_name, obj_expr); 
    new_array) (* insert the macro at tail *) 
... 
;; 


### main method ### 
let storage = Array.make 10 ((x : string), (a, b)) in 
... 
while true do 
... 
storage = function_that_adds_to_array storage args....; 
... 

在function_that_adds_to_array(...)末尾的打印語句確認一個新的數組返回,包含初始陣列的舊元素,然而,在主要方法,存儲保持一致。這是因爲OCaml元素的不變性嗎?我以爲陣列是可變的。我環顧四周,還有一些人提到黑客想讓OCaml像Perl一樣行事,但是,使用一個人的resize黑客功能證明是徒勞的。任何方式我可以讓存儲成爲一個新的陣列?它需要是一個可更新的元組集合(即(string,(x,y)))?

+2

如果你不是這樣做的教育目的,我會建議看看電池的[dynarray](http://ocaml-batteries-team.github.com/batteries-included/hdoc2/BatDynArray.html) – rgrinberg

+0

我喜歡這個庫,但是,它似乎沒有包含在標準的OCaml發行版中(我把合適的開放和包含調用,但它告訴我它是一個未綁定的模塊)。你能否爲我提供一個獲取和安裝最新版BatDynArray及其所需庫的好鏈接? – 9codeMan9

+3

安裝[OPAM](http://opam.ocamlpro.com/doc/Quick_Install.html)。然後做'opam安裝電池'。 「#require」電池;;「'接着打開電池;'' – rgrinberg

回答

4

在OCaml中,您不能指定變量,句點。數組沒有特別的限制。但是,可以有一個綁定到引用的變量,該引用可以保存相同類型的不同值。這種結構在命令式語言中通常被稱爲「變量」。有不同大小的數組變量中x你如下可以寫代碼:

# let x = ref [| 0 |];; 
val x : int array ref = {contents = [|0|]} 
# Array.length x;; 
Error: This expression has type int array ref 
    but an expression was expected of type 'a array 
# Array.length !x;; 
- : int = 1 
# x := [| 2; 3 |];; 
- : unit =() 
# Array.length !x;; 
- : int = 2 

!運營商取消引用的參考,並:=運營商分配新值。

如果您是OCaml的新手,我將包括我的標準建議,您應該在決定重新創建您已知的命令式語言的模式之前調查使用不可變數據。如果你不是OCaml的新手,我爲我的無禮道歉!

+1

命名很困難,特別是關於命名的命名!但我認爲事物在FP世界歷史上稱爲變量(在lambda微積分中)。 –

+0

完全同意你的看法。我不知道歷史術語,謝謝! – didierc

+1

我同意瞭解有關不可變數據的更多信息。我對OCaml並不陌生,因爲在過去的幾個月裏我一直在使用它,但是在將命令式編程轉換爲函數式編程之間遇到了一些困難。有些東西可以很好地轉換,比如遞歸思考而不是標準循環,但是我發現訪問命令式語言中更容易找到的某些功能比較容易,例如動態數組。 – 9codeMan9