2011-09-30 11 views
2

のリストを反復処理し、要素をスキップこれはやって奇妙なことのように思えるかもしれません、あなたは確かにそれを行うには良い方法を提案することを歓迎しています。私は関数に渡されたリストの各要素をスクロールしたいのOCaml:もし間違ってコンストラクタ

は、ここに私の目標です。それがコンストラクタYの場合は、その上でいくつかの関数を呼び出す必要があります。それがコンストラクタZの場合、私はそれをスキップしたいと思います。

if文でこれをチェックする方法があれば、私は他を記述する必要はないので、それが進むべき道のように思えます。しかし、私は試合でこれをチェックする方法しか知りません。例えば

let myFunct list = 
List.iter (fun x -> match x with 
      | Y y -> otherFunction y 
     ) list;; 

さて、これは私にだから私のような存在で何かを投げることができZ.を扱うことができないという警告を与える...もちろん

let myFunct list = 
List.iter (fun x -> match x with 
      | Y y -> otherFunction y 
      | Z z -> (*skip*) 
     ) list;; 

、私はちょうど空白Zの試合を残すことはできません....

私は私が何をしようとしている達成することができますどのように?

+0

(リストのすべての要素は同じ型です.OCamlの厳密な型定義がこれを強制します。同じ型の異なるコンストラクタについて話しています) –

+0

"同じリストに異なるタイプの要素を含めることができるという意味で「タイプ」します。 「コンストラクタ」は、可能性の低い過度のシノニムです。 –

+0

注釈と固定 –

答えて

1

List.filterを使用すると、条件に基づいてリストをフィルタリングし、フィルタリングされたリストでList.iterを使用できます。

リストモジュールのメソッドの詳細については、こちらのドキュメントを参照してください。 http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html

私は、現時点ではOCamlのコンパイラにアクセスすることはできませんが、コードは次のようになります:

List.iter (fun x -> ....) (List.filter (fun x -> ...) mylist)

+0

List.filterの使い方は分かりません。私が知る限り、特定のコンストラクタを持つことは、条件を確認することはできませんが、一致する必要があります。私は間違っていますか?どうすればこれを達成できますか? –

+0

私の問題は、どのようにコンストラクタに基づいて一致させることです、私はまだフィルタ関数でこれを行う必要があります。 –

+0

@CaseyPatton ah ok - 私はあなたの質問の要点を逃しました。はい、まだマッチステートメントを使用する必要があります。私はそれを行うための他の方法を知らない。 – sashang

6

だけ返し単位(すなわち、()Zケースを。

あなたが List.iterをよろしいです。これは主に、その副作用のために関数を適用するために使用されます。

機能プログラムでもっと慣用的なアプローチは、List.filterを使用してリストをフィルタリングし、残りのすべての要素にList.mapを使用して変換を適用することです。 List.iterため

+2

'List.map'を適用する前に即座に破棄される中間リストを作成するために' List.filter'を最初に適用すると良いスタイルであるとは私は同意しません。 –

+0

@Pascal私はそれが機能的な言語に慣れていない人にとっては優れた学術的テクニックだと思います。 – Lambdageek

+4

レスキュー用の 'List.filter_map' – ygrek

1

Lambdageekの答えは正しいです。何もする必要がない場合には、結果として()を使用するだけです。 match式の異なるケースはすべて、反復処理を実行するときにreturn()する必要があります。それはList.iterのすべてです。他

誰もがあなたが本当にList.iterを使用したくないかもしれないと心配(当然、私の意見では)です。これは、他の(命令的な)言語から来たときに考えている最初のものかもしれませんが、それ自体はは関数型プログラミングを行うときによく使われるものではありません。あなたが何らかのコースでOCamlを学んでいるのであれば、List.iterを使用する可能性はさらに低くなります。 OCamlのコースは、間違いなく機能の部分をカバーすることから始まります。機能的に考えるには、値をあるフォームから別のフォームに変換すること(つまり、関数を関数に適用すること)について考える必要があります。

List.filterを使用したいとします。あなたが言うように、あなたはmatch式を終わらせますが、すべての異なるケースでreturning()の代わりに、それぞれの場合にブール値(trueまたはfalse)を返すことを望みます。 trueを返すと、結果のリストに値が含まれます。 falseを返すと、結果のリストに値は含まれません。もう一度、それはList.filterがすべてについてです。 Zのコンストラクタを持つ指定されたリストの要素だけを含む新しいリストを返すコードがいくつかあります。

let myFunc list = 
    List.filter 
     (fun x -> match x with Z _ -> true | _ -> false) 
     list 

私はこのことができますわからないんだけど、私は私が言うことをしようとしていることmatchを使用することは困難ではないことだと思います。あなたはすべてのケースをカバーする必要があります。これは良いことです、あなたはすべての場合にあなたのコードを動作させたい!

関連する問題