20

OCaml を使用して一連のデータを生成し、それらを比較したいと考えています。Set.OrderType、 などのモジュール タイプのドキュメントを見たSet.Makeことがありますが、セットを初期化する方法やそれらを使用する方法がわかりません。

4

2 に答える 2

32

セットは、ファンクトリア インターフェイスを使用して定義されます。任意のタイプについて、ファンクタSetを使用してそのタイプのモジュールを作成する必要があります。標準ライブラリの残念な見落としは、組み込み型のインスタンスをSet.Make定義していないことです。Setほとんどの単純なケースでは、 を使用するだけで十分Pervasives.compareです。で機能する定義は次のintとおりです。

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

モジュールはインターフェースIntSetを実装しSet.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 に対する多くの有用な操作を宣言しています。)

于 2009-09-20T23:25:33.250 に答える
12

OrderedTypeChris の回答に加えて、いくつかの標準ライブラリ モジュールが既に署名に準拠していると言うのは役に立つかもしれません。たとえば、次のように簡単に実行できます。

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 *)
于 2009-09-21T14:35:04.877 に答える