2012-02-12 23 views
2

我有一個(int *字符串)元組,我想轉換成列表。該元組的形式是(N,E),其中N是元素E的出現次數。 該函數應該返回一個列表,其中包含N個出現次數爲E的列表。示例如下。讓我們假設這個函數被稱爲tuple_decode。Ocaml函數將元組轉換爲列表

tuple_decode (1, "A") -> ["A"] 
tuple_decode (2,"B") -> ["B";"B"] 
tuple_decode (4,"C") - > ["C";"C";"C";"C"] 

的tuple_decode功能如下

let tuple_decode acc (n,elem) = 
let add_one_elem i = 
    match i with 
      0 -> acc 
     | i -> elem :: acc ; add_one_elem (i-1) (* Line 184 *) 
in 
add_one_elem n 
;; 

,當我嘗試編譯這個功能我得到以下錯誤。

File "all_code.ml", line 184, characters 11-22: 
Warning 10: this expression should have type unit. 
File "all_code.ml", line 184, characters 25-37: 
Error: Unbound value add_one_elem 

有人可以幫我找出爲什麼我得到這個錯誤和警告。

問候 普尼特

回答

6

警告使用;來自序列組成。當您編寫S1 ; S2時,編譯器預計S1的類型爲unit。但是這裏的S1返回一個清單(elem::acc,其價值將被丟棄。此外,由於您沒有通過acc作爲參數,所以在所有遞歸調用後,其值不會改變。

該錯誤是由於遞歸使用add_one_elem。因爲您沒有使用rec關鍵字,所以當調用add_one_elem (i-1)時,OCaml不知道add_one_elem正在被遞歸定義。

此外,acc應該是add_one_elem參數積累的結果:

let tuple_decode (n, elem) = 
    let rec add_one_elem i acc = 
     match i with 
     | 0 -> acc 
     | i -> add_one_elem (i-1) (elem::acc) 
    in add_one_elem n [] 
+2

而且,有趣的是,在警報部分,如果'S1'沒有類型'unit'那麼結果被扔掉。所以如果你沒有將累加器作爲參數傳遞給你的函數,那麼遞歸調用就沒用了。 – Thomas 2012-02-12 10:03:51

+0

謝謝,我添加了你的建議,使答案更清晰。 – pad 2012-02-12 10:11:19