13

ファンクター(およびその結果のタイプ)に少し問題があります。以下に、Orderedタイプを使用するSetファンクターがあります。私は実際set.mlにいくつかのガイダンスのためにocamlに付属しているものを使用しましたが、私はすべてを正しく行っているようです。整数を使用してOrderedモジュールを作成し、それをSetファンクターに適用して、このコードサンプルの最後のモジュールであるIntSetを取得しました。

整数を挿入しようとすると、次の行が失敗します。次のタイプエラーが発生します。

Error: This expression has type int but is here used with type
         SetInt.elt = Set(OrdInt).elt

誤解しないでください。ここでは型システムが正しいです。SetInt.eltトップレベルはのタイプがであると報告していSet(OrdInt).eltますが、同じ操作を行ってocamlが提供するものを使用してセットを設定すると、「同じ」行は、SetInt.elt = OrderedInt.tです。私が取得する必要があるようSetInt.elt = Ordered.tです。

これはとても単純なので、私はおそらくいくつかの愚かな詳細が欠けています!ああ!

注意:この問題は型に関係しているため、ここではメンバー/挿入関数を簡略化しました。

module type Ordered =
  sig
    type t 
    val lt : t -> t -> bool
    val eq : t -> t -> bool
    val leq : t -> t -> bool
  end

module type S =
  sig
    type elt
    type t
    exception Already_Exists
    val empty  : t
    val insert : elt -> t -> t
    val member : elt -> t -> bool
  end

module Set (Elt:Ordered) : S = 
  struct
    type elt = Elt.t
    type t = Leaf | Node of t * elt * t
    exception Already_Exists
    let empty = Leaf
    let insert e t = t
    let member e t = false
  end

module OrdInt : Ordered =
  struct
    type t = int
    let lt a b = a < b
    let eq a b = a = b
    let leq a b = a <= b
  end

module IntSet = Set (OrdInt)

(* line that fails *)
let one_elm = IntSet.insert 1 IntSet.empty
4

1 に答える 1

15

これらの2行を変更する必要があります

module Set (Elt:Ordered) : S = 
module OrdInt : Ordered =

module Set (Elt:Ordered) : S with type elt = Elt.t = 
module OrdInt : Ordered with type t = int =

これらがないと、モジュールには、タイプeltおよびtをintとして公開するシグニチャがありません。

[編集]:set.mlには「with」ビットがありません。ファンクターの署名を宣言するsml.mliがあり、「with」があるためです。また、次のように署名を明示的に指定しない場合、OrdIntは「with」を必要としません。

module OrdInt =

モジュールを所定の位置に定義してセットを作成することもできます。

module IntSet = Set (struct
 type t = int
 let lt a b = a < b
 let eq a b = a = b
 let leq a b = a <= b
end) 
于 2009-03-12T21:24:17.560 に答える