2

どの種類の値が最初であるかを見つける必要があるいくつかの値のリストがあります:

type my_types =
    | MAlpha
    | MBeta of int list
    | MGamma of string * int

let find_first where what =
    List.iter ( fun m ->
        | MAlpha ->
            (* iterate frough "what" to find if it was asked to look and return it if it was *)
        | (* do the same for all other types *)
    ) where;
;;

let main =
    let where_to_find = [MGamma, MAlpha, MBeta] in
    let what_to_find = [MAlpha, MBeta] in
    (match (first_found where_to_find what_to_find) with
    | MAlpha ->
        (* should return this *)
    )
;;

find_first内のすべてのタイプのMyTypeに触れることなくこれを行う方法はありますか?2つの値のタイプを比較することは可能ですか?ありがとうございました。

4

2 に答える 2

4

あなたが投稿したコードはコンパイルされませんが、私はあなたが次の情報を探していると思います:

  1. たとえば、のように、いわゆるor-patternsを書くことができます(function MAlpha | MBeta _ -> ...)

  2. しかし、パターンは一級市民ではありません。リストからパターンを作成することはできません(ちなみに、[MGamma, MAlpha, MBeta]これは質問でコンパイルされないものの1つです)。また、関数の引数としてパターンを渡すこともできません。

  3. ただし、パターンに一致する関数を作成して渡すことができるため、関数を変更してfind_first、のリストではなく関数を取得する場合whatは、より便利に使用できます。

于 2011-09-24T12:05:57.297 に答える
3

これを見る別の方法は、あなたがあなたのタイプに対して同値関係を持っているということです。MAlphaつまり、すべてを同じ、すべてを同じ、すべてを同じMBetaに扱いたい場所がいくつかありますMGamma。同値関係の標準的な処理は、同値のセット全体(同値類)を表す代表的な要素を選択することです。

あなたの場合MAlpha、すべてのsを表すために使用できますMAlpha(ただし、そのうちの1つだけです)、MBeta []すべてのsを表すため、およびすべてのMBetasMGamma ("", 0)を表すために使用できますMGamma。与えられたものから代表値を計算する関数があります:

let malpha = MAlpha
let mbeta = MBeta []
let mgamma = MGamma ("", 0)

let canonicalize =
    function
    | MAlpha -> malpha
    | MBeta _ -> mbeta
    | MGamma _ -> mgamma

let find_first where what =
    canonicalize (List.find (fun x -> List.mem (canonicalize x) what) where)

let main () =
    let where_to_find = [MGamma ("a", 3); MAlpha; MBeta [3; 4]] in
    let what_to_find = [malpha; mbeta] in
    try
        let found = find_first where_to_find what_to_find
        in
            if found = malpha then (* what to do *)
            else if found = mbeta then (* what to do *)
            else (* what to do *)
    with Not_found -> (* nothing was there *)

私はこのようなコードを書きましたが、それほど悪くはありません。あなたの場合、それはあなたがwhatパラメータを少し自然に指定することを可能にします。ただし、欠点の1つは、、、およびとmalphaのパターンマッチングができないことです。あなたはそれらに対して平等の比較をしなければなりません。mbetamgamma

正規化された値ではなく、リスト内の特定の値を見つけたい場合があります。その場合の変更はかなり明確なはずだと思います。

これはあなたの質問の2番目の部分にも答えます。List.find探しているものが見つかるとすぐに関数は停止します。

OCamlは、機能値を含まないすべてのタイプの順序関係を定義します。この組み込み(多態性)の順序付けで目的の結果が得られない場合は、独自の順序付けを定義する必要があります。2つの異なるタイプの値を比較するには、確かにこれを行う必要があります。しかし、それはあなたがここでしていることではありません。

希望どおりの要素がリストにない場合、このバージョンでfind_firstは例外が発生しますNot_found。それは別のことを考える必要があります。

于 2011-09-24T15:27:08.153 に答える