これを見る別の方法は、あなたがあなたのタイプに対して同値関係を持っているということです。MAlpha
つまり、すべてを同じ、すべてを同じ、すべてを同じMBeta
に扱いたい場所がいくつかありますMGamma
。同値関係の標準的な処理は、同値のセット全体(同値類)を表す代表的な要素を選択することです。
あなたの場合MAlpha
、すべてのsを表すために使用できますMAlpha
(ただし、そのうちの1つだけです)、MBeta []
すべてのsを表すため、およびすべてのMBeta
sMGamma ("", 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
のパターンマッチングができないことです。あなたはそれらに対して平等の比較をしなければなりません。mbeta
mgamma
正規化された値ではなく、リスト内の特定の値を見つけたい場合があります。その場合の変更はかなり明確なはずだと思います。
これはあなたの質問の2番目の部分にも答えます。List.find
探しているものが見つかるとすぐに関数は停止します。
OCamlは、機能値を含まないすべてのタイプの順序関係を定義します。この組み込み(多態性)の順序付けで目的の結果が得られない場合は、独自の順序付けを定義する必要があります。2つの異なるタイプの値を比較するには、確かにこれを行う必要があります。しかし、それはあなたがここでしていることではありません。
希望どおりの要素がリストにない場合、このバージョンでfind_first
は例外が発生しますNot_found
。それは別のことを考える必要があります。