2012-02-12 21 views
2

私はリストに変換したい(int * string)タプルを持っています。タプルの形式は(N、E)です。ここで、Nは要素Eの出現数です。 この関数は、N個の出現箇所を持つリストを返します。例は次のとおりです。この関数がtuple_decodeと呼ばれると仮定します。タプルをリストに変換するOcaml関数

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 
;; 

を次のように私は次のエラーを取得するこの関数をコンパイルしようとすると

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

tuple_decode関数です。

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 

私はこのエラーと警告が表示される理由を理解できますか?

よろしく Puneet

答えて

6

警告が;を使用して配列の組成から来ています。 S1 ; S2と記述すると、は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

+0

ありがとうございます、私はあなたの提案を答えを明確にするために追加しました。 – pad

関連する問題