Ocaml中的函子 [英] Functors in Ocaml
问题描述
我有一个函子的一个问题(和它的结果类型)。下面,我有一个使用Ordered类型的Set函子。我实际上使用了ocaml附带的 set.ml
作为一些指导,但我似乎正在做一切正确的事情。我创建了一个有整数的Ordered模块,并将其应用到Set函数中,以获取此代码示例IntSet上的最后一个模块。
下一行失败,当我尝试插入一个整数。我得到以下类型的错误:
错误:此表达式具有类型int,但在此处与类型
SetInt一起使用。 elt = Set(OrdInt).elt
不要误解我的意思,类型系统在这里是正确的。顶层报告 SetInt.elt
的类型是 Set(OrdInt).elt
,但是当我做使用ocaml提供的'same'行创建Set的相同操作是 SetInt.elt = OrderedInt.t
。似乎我应该得到 SetInt.elt = Ordered.t
。
这很简单,我是可能只是错过了一些愚蠢的细节!请注意:由于此问题与类型有关,因此我简化了成员/插入函数。
模块类型Ordered =
sig
type t
val lt:t - > t - > bool
val eq:t - > t - > bool
val leq:t - > t - > bool
end
模块类型S =
sig
type elt
类型t
异常Already_Exists
val空:t
val插入:elt - > t - > t
val member:elt - > t - > bool
end
模块Set(Elt:Ordered):S =
struct
type elt = Elt.t
type t = Leaf |节点t * elt * t
异常Already_Exists
让empty = Leaf
让insert et = t
let member et = false
end
模块OrdInt:Ordered =
struct
type t = int
let lt ab = a< b
let eq ab = a = b
let leq ab = a <= b
end
模块IntSet = Set(OrdInt)
(*失败的行)
let one_elm = IntSet.insert 1 IntSet.empty
您需要更改这两行
module Set(Elt:Ordered ):S =
模块OrdInt:Ordered =
到
模块Set(Elt:Ordered):S with type elt = Elt.t =
模块OrdInt:与类型t = int =
如果没有这些,模块将没有签名将类型elt和t公开为int。
:
set.ml没有'with'位,因为有一个sml.mli,它声明函子的签名,它确实有'与'。另外,如果你没有明确指定它的签名,OrdInt不需要'with',就像这样:
module OrdInt =
您也可以通过定义模块来构建集合:
module IntSet = Set(struct
type t = int
let lt ab = a< b
let eq ab = a = b
let leq ab = a <= b
end)
I am having a bit of a problem with a functor (and it's resultant type). Below, I have a Set functor that uses an Ordered type. I actually used the set.ml
that comes with ocaml for some guidance, but I seem to be doing everything ahhem right. I created an Ordered module with integers and applied it to the Set functor to get the last module on this code sample, IntSet.
The next line fails, when I try to insert an integer. I get the following type error:
Error: This expression has type int but is here used with type
SetInt.elt = Set(OrdInt).elt
Don't get me wrong, the type system is correct here. The top level reports that the type of the SetInt.elt
is Set(OrdInt).elt
, but when I do the same operations to set up a Set using the one provided by ocaml the 'same' line is, SetInt.elt = OrderedInt.t
. Seems like I should be getting SetInt.elt = Ordered.t
.
This is so simple, I'm probably just missing some stupid detail! argh!
Please Note: I have simplified the member/insert functions here since this issue has to do with types.
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
You need to change these two lines
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 =
Without these, the modules will not have signatures that expose the types elt and t as int.
[Edit]: The set.ml doesn't have the 'with' bit, because there's a sml.mli, which declares the signature for the functor and it does have the 'with'. Also, OrdInt doesn't need 'with' if you don't explicitly specify a signature for it, like this:
module OrdInt =
You can also construct the set by defining the module in place:
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)
这篇关于Ocaml中的函子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!