2011-01-13 18 views
4

各繰り返しでリストのすべての値を再帰的に返す(印刷しない)関数が必要です。しかし、私はこれをプログラミングしようとするたびに、代わりにリストを返します。リスト内のすべての値を返す再帰関数(OCaml内)

let rec elements list = match list with 
| [] -> [] 
| h::t -> h; elements t;; 

は、私は、各要素、それは私が書いた別の関数に返されるたびに使用する必要があるので、私は一度にこれらの要素の1が必要ですが、私はこの部分を把握することはできません。どんな助けもありがとう。

let rec elements list = 
    match list with 
    | [] -> [] 
    | h :: t -> elements t 

a ; baを評価(および結果を破棄)してから評価し、bを返すので、これが起こる:

答えて

3

あなたの機能は同等です。明らかに、これは次と等価です:

let elements (list : 'a list) = [] 

これはあまり有用な機能ではありません。

しかし、これを解決する前に、Objective Caml関数は1つの値を返すことができます。複数の値を返すことは不可能です。

この制限を回避する方法があります。 1つの解決策は、返す値をすべて単一の値にまとめることです。通常、タプルまたはリストです。あなたは、任意の数の要素を返す必要があれば、あなたはリストにそれらを一緒にパックし、一覧表示し、呼び出し元のコード処理しています:別の頻度の低いソリューションが機能を提供し、それを呼び出すことです

let my_function() = [ 1 ; 2; 3; 4 ] in (* Return four values *) 
List.iter print_int (my_function()) (* Print four values *) 

をすべての結果:

let my_function action = 
    action 1 ; 
    action 2 ; 
    action 3 ; 
    action 4 
in 
my_function print_int 

これはリストを返すよりも、柔軟性に劣るが、間違いなく高速です:リストは、フィルタ並べ替え、保存することができます...

+0

ありがとうございます。私はあなたが説明したように、2つのステップで2つのステップでこれを行うことを考えていますが、私の問題は、各要素を1つずつ取り出すことです。私は少し具体的にすべきだ。私の主な機能は、リストaがリストbのサブセットであるかどうかを判断するタスクが与えられているサブセット関数です。私はこの関数を多態的な形で書く必要がありますが、今はintのリストでそれを行う方法しか分かりません。 – Atticus

+0

問題は、リストの最初の要素を返す関数を作成したためです:let head list = list with h :: t - > h | [] - > 0。空のリストを考慮する必要があるので、私は0を返し、OCamlはこの関数がintのリストを取ると判断します。サブセット関数は多態的でなければならないので、空のセットに対して何を返すべきかを事前に知ることはできません。0、 "null"などです。したがって、これはintのリストに制限されます。この場合、 – Atticus

+0

(空リストの返り方)は、単にエラーを発生させます:(failwith "error") – gasche

1

あなたの質問は一種の混乱です - あなたは機能が欲しいですリスト内のすべての値を返します。可変数の値を返す最も簡単な方法は、リストを使うことです!あなたはおそらくPythonジェネレータをエミュレートしようとしていますか? OCamlにはyieldと似たものはありませんが、代わりに通常は(iterfoldまたはmapを使用して)値に関数を渡すことで同じ結果が得られます。あなたがこれを行うにしようとしている場合

def elements(list): 
    if(len(list) == 0): 
     return [] 
    else: 
     list[0] 
     return elements(list[1:]) 

:OCamlの中で

def elements(list): 
    if(len(list) > 0): 
     yield list[0] 
     # this part is pretty silly but elements returns a generator 
     for e in elements(list[1:]): 
      yield e 

for x in elements([1,2,3,4,5]): 
    dosomething(x) 

同等のものを、次のようになりますあなたが現在書かれているPythonでこれに相当します

List.iter dosomething [1;2;3;4;5] 

リストaがリストbのサブセットであるかどうかを判断しようとしている場合(あなたのコメント)、その後はList.memList.for_allを活用することができる。

List.for_all (fun x -> List.mem x b) a 

fun x -> List.mem x bは、値x)はBのメンバーである(任意の要素と同じである場合に真を返す関数を定義します。 List.for_allはbool(ここでは今定義したメンバーシップ関数)とリストを返す関数を取ります。この関数はリストの各要素に適用されます。この関数がリストのすべての値に対してtrueを返す場合、for_allはtrueを返します。

私たちがしたことは:aのすべての要素について、それらがbのメンバーであるかどうかを確認します。これらの関数を自分自身で書く方法に興味があるなら、list.mlのソースを読むことをお勧めします。これはおそらく/ usr/local/lib/ocamlまたは/ usr/lib/ocamlにあります。