Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Module 理解OCaml中的函子_Module_Ocaml_Functor - Fatal编程技术网

Module 理解OCaml中的函子

Module 理解OCaml中的函子,module,ocaml,functor,Module,Ocaml,Functor,我在OCaml中遇到了以下函子问题。我粘贴一些代码只是为了让您理解。基本上 我在pctl.ml中定义了这两个模块: module type ProbPA = sig include Hashtbl.HashedType val next: t -> (t * float) list val print: t -> float -> unit end module type M = sig type s val set_error: float -&

我在OCaml中遇到了以下函子问题。我粘贴一些代码只是为了让您理解。基本上

我在
pctl.ml
中定义了这两个模块:

module type ProbPA = sig
  include Hashtbl.HashedType  
  val next: t -> (t * float) list
  val print: t -> float -> unit
end

module type M = sig
  type s  
  val set_error: float -> unit
  val check: s -> formula -> bool
  val check_path: s -> path_formula -> float
  val check_suite: s -> suite -> unit
end
type state = value array
type t = state
type value =
  | VBOOL of bool
  | VINT of int
  | VFLOAT of float
  | VUNSET
(* all the functions required *)
和以下函子:

module Make(P: ProbPA): (M with type s = P.t) = struct
  type s = P.t
  (* implementation *)
end
然后,为了实际使用这些模块,我直接在名为
prism.ml的文件中定义了一个新模块:

module type ProbPA = sig
  include Hashtbl.HashedType  
  val next: t -> (t * float) list
  val print: t -> float -> unit
end

module type M = sig
  type s  
  val set_error: float -> unit
  val check: s -> formula -> bool
  val check_path: s -> path_formula -> float
  val check_suite: s -> suite -> unit
end
type state = value array
type t = state
type value =
  | VBOOL of bool
  | VINT of int
  | VFLOAT of float
  | VUNSET
(* all the functions required *)
从第三个来源(
formulas.ml
)我将函子与
Prism
模块一起使用:

module PrismPctl = Pctl.Make(Prism)
open PrismPctl
最后从
main.ml

open Formulas.PrismPctl
(* code to prepare the object *)
PrismPctl.check_suite s.sys_state suite (* error here *)
和compiles给出以下错误

错误:此表达式的类型为Prism.state=Prism.value数组 但应为Formulas.PrismPctl.s类型的表达式

从我可以理解的名称中有一种不好的混淆,它们是相同的(因为<代码>值数组< /代码>是定义为<代码> t>代码>的类型,并且在函数中使用了“s>p.t/<代码>类型的代码> m,但是类型检验者不认为它们是相同的。

我真的不明白问题出在哪里,有人能帮我吗


提前感谢

这是我在了解更多信息时遇到的一个问题。创建函子时,将公开函子的签名,在本例中为
M
。它包含一个抽象类型
s
,由functor参数化,任何更具体的内容都不会对外公开。因此,访问
s
的任何记录元素(如
sys\u state
)将导致类型错误,正如您所遇到的那样

其余的看起来不错。正确使用functor肯定很难,但请记住,您只能通过functor公开的接口/签名操作functor参数化类型的实例。

(你发布不可编译的代码。这是一个坏主意,因为这可能会让人们更难帮助你,因为把你的问题简化为一个简单的例子有时就足以解决它。但我想我还是看到了你的困难。)

formulas.ml
中,Ocaml可以看到
PrismPctl.s=Pctl.Make(Prism.t=Prism.t
;第一个等式来自
PrismPctl.Make
的定义,第二个等式来自
Pctl.Make
的签名(特别是带有s=p.t
位类型的

如果你没有为
公式
编写
mli
文件,你的代码应该编译。所以问题一定是你编写的
.mli
文件没有提到正确的相等性。你没有显示你的
.mli
文件(你应该,它们是问题的一部分),但大概是你编写的

module PrismPctl : Pctl.M
这还不够:当编译器编译
main.ml
时,它不会知道
PrismPctl
中没有在
formulas.mli
中指定的任何内容。您需要指定其中一个

module PrismPctl : Pctl.M with type s = Prism.t
或者,假设您在
pctl.mli

module PrismPctl : Pctl.M with type s = Pctl.Make(Prism).s

我对OCaml知之甚少,无法提供帮助,但前面的问题是否也可能是类似的问题?@Gian:这是同一个根本问题,但如果你理解了这一点,那么你已经在一开始就不需要问这个问题了。这就是问题所在。我昨天通过查看问题的答案意识到了这一点n由gian在评论中链接。我没有粘贴我的
.mli
文件,因为我忘了粘贴。我的错!谢谢