質問

私はOCamlは、データのセットを生成するために使用し、それらの間の比較をしたいです。私はなどSet.OrderTypeSet.Make、のようなモジュールの種類のドキュメントを見てきましたが、私はセットを初期化するか、そうでない場合は、それらを使用する方法を見つけ出すことはできません。

役に立ちましたか?

解決

セットはfunctorialインタフェースを使用して定義されています。任意のタイプのために、あなたはSetファンクタを使用してそのタイプのSet.Makeモジュールを作成する必要があります。標準ライブラリの不幸な監督は、彼らがビルトインタイプのためSetインスタンスを定義していないということです。最も単純なケースでは、それはPervasives.compareを使用することで十分です。ここでintのために働くの定義があります:

module IntSet = Set.Make( 
  struct
    let compare = Pervasives.compare
    type t = int
  end )

モジュールIntSetSet.Sインターフェイスを実装します。今、あなたはIntSetモジュールを使用してセットを操作することができます:

let s = IntSet.empty ;;
let t = IntSet.add 1 s ;;
let u = IntSet.add 2 s ;;
let tu = IntSet.union t u ;;

あなたが明示的にSet.MakeとしてOrderedTypeの入力構造を定義する必要はないことに注意してください。型推論はあなたのための作業を行います。また、あなたは次の定義を使用することができます:

module IntOrder : Set.OrderedType = struct
  type t = int
  let compare = Pervasives.compare
end

module IntSet = Set.Make( IntOrder )

これは、あなたがMapをインスタンス化するために同じモジュールを再利用できるという利点があります:

module IntMap = Map.Make( IntOrder )

あなたは元素の種類が固定されているため、ファンクタを使用して、いくつかの一般性を失います。たとえば、あなたはいくつかの任意のタイプのSetを取り、その上にいくつかの操作を実行する関数を定義することができません。 (幸いにも、Setモジュール自体がSetsに多くの有用な操作を宣言する。)

他のヒント

クリスの答えに加えて、いくつかの標準ライブラリモジュールが既にOrderedType署名を遵守することを言うために有用である可能性があります。たとえば、あなたは、単に行うことができます:

module StringSet = Set.Make(String) ;;       (* sets of strings *)
module Int64Set = Set.Make(Int64) ;;         (* sets of int64s *)
module StringSetSet = Set.Make(StringSet) ;; (* sets of sets of strings *)

のように。

ここでStringSetのための簡単な使用例を示します。セットは、機能データ構造であることを覚えているので、セットに新しい要素を追加すると、新しいセットを返します:

let set = List.fold_right StringSet.add ["foo";"bar";"baz"] StringSet.empty ;;
StringSet.mem "bar" set ;; (* returns true *)
StringSet.mem "zzz" set ;; (* returns false *)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top