2016-07-16 20 views
0

リストに追加することでユニークなリストを作成しようとしていますが、このエラーが発生しています。OCamlの条件に基づいてリストに追加する

Error: This expression has type 'a list 
     but an expression was expected of type unit 

in_listは、値がリストにあるかどうかをチェックするブール関数です。

if(in_list x seen_list) then print_string("Already found") else [email protected] in 
    List.iter uniq check_list;; 

私は追加機能のために修正する必要があるいくつかの小さな構文エラーがあるようです。提案?

答えて

0

これは構文エラーではなくタイプエラーです。

OCaml関数は、常に同じ型の結果を返す必要があります。今、アイテムがリストにあるとき、あなたの関数はアイテムがリストにない場合とは異なるタイプを返そうとします。

具体的には、アイテムが既に存在する場合、関数はprint_stringを呼び出し、()を返します。これはunitと呼ばれ、興味深い値を表さないプレースホルダーです。項目がまだ存在しない場合、関数は'a listの値を返します。あなたがする必要があるのは、すべてのケースでリストを返すことです。

あなたのコードをもっと見ることなくもっと言うことは難しいですが、この状況を処理する最も一般的な方法は、アイテムが既に存在するときに古いリストを戻し、アイテムが既に存在しないときに新しいより長いリストを返すことですそこ。

更新

は、このコードで修正する多くのものがありますが、それは私が前提と運動のポイントです。

次の問題は、List.iterが必須の機能であると思われます。つまり、結果を生成するのではなく、を実行します。したがって、リストを反復する関数はユニットを返す必要があります(前述)。代わりに関数uniqを使用しています。これはリストを返します。

優れたOCamlスタイルのList.iterなどの高次関数を使用する場合は、結果を累積することを目的とした折り畳み(List.fold_leftまたはList.fold_right)を使用する必要があります。

+0

どのようなタイプにする必要がありますか?print文を '[1; 2; 3]'に変更すると、 'エラー:この式はint型のリスト - > intリスト ですが、式はint型のリストであることが期待されます - > int型型ユニット ' –

+0

と互換性がありません関数を多型にしたい場合は、入力リストと同じ型のものを返す必要があります。実際、このケースでは、入力リスト自体を返すだけです。すべてのコードを見ることなく確実に確認するのは難しいです。 –

1

TL; DRは:リストがあなたのコードによるとOCamlの

に不変である、あなたはリストがOCamlの中で変更可能であると考えているようだ、とそうではありません。したがって、[email protected]は新しいリストを計算しますが、seen_listは変更されません。

は、あなたはそれがスキップしたエントリをログに記録、繰り返しなし

let uniq seen_list x = 
    if in_list x seen_list then 
    (Printf.printf: "uniq: %d: Already seen.\n" x; seen_list) 
    else x :: seen_list 
in 
List.fold_left uniq [] check_list 

uniq関数は整数のリストに整数のリストをマップにコードを変更することができます。

このコードは明らかに教材であることを意図していますが、それにもかかわらず、Shlemiel the painter's algorithmが実装されている可能性が高いことに注意してください。

関連する問題