OCaml 中的函子
我在函子(及其结果类型)方面遇到了一些问题。 下面,我有一个使用 Ordered
类型的 Set
函子。 我实际上使用了 OCaml 附带的 set.ml
来获取一些指导,但我似乎一切都做对了。 我创建了一个包含整数的 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
。
这很简单,我可能只是错过了一些愚蠢的细节! 啊!
请注意:我在这里简化了成员/插入函数,因为这个问题与类型有关。
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
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 ahem 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要将这两行更改
为
如果没有这些,模块将不会具有将类型 elt 和 t 公开为 int 的签名。
[编辑]:
set.ml 没有“with”位,因为有一个 sml.mli,它声明函子的签名并且它确实有“with”。 此外,如果您没有显式为其指定签名,则 OrdInt 不需要“with”,如下所示:
您还可以通过就地定义模块来构造集合:
You need to change these two lines
to
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:
You can also construct the set by defining the module in place: