Ocamlのファンクター
-
11-07-2019 - |
質問
ファンクターに少し問題があります(その結果の型です)。以下に、Ordered型を使用するSetファンクターがあります。実際には、ocamlに付属の set.ml
をいくつかのガイダンスに使用しましたが、 ahhem のすべてを正しく行っているようです。整数で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
であると報告されますが、提供されたものを使用して同じ操作を行ってSetを設定するとocamlでは、「同じ」行は SetInt.elt = OrderedInt.t
です。 SetInt.elt = Ordered.t
を取得する必要があるようです。
これは非常に単純なため、愚かな詳細が欠落しているだけでしょう。 argh!
注意:この問題は型に関係しているため、ここでメンバー/挿入関数を簡略化しました。
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
解決
これらの2行を変更する必要があります
module Set (Elt:Ordered) : S =
module OrdInt : Ordered =
to
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)
所属していません StackOverflow