理解OCaml中的仿函数

Jac*_*ack 8 ocaml module 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 -> unit
  val check: s -> formula -> bool
  val check_path: s -> path_formula -> float
  val check_suite: s -> suite -> unit
end
Run Code Online (Sandbox Code Playgroud)

以及以下仿函数:

module Make(P: ProbPA): (M with type s = P.t) = struct
  type s = P.t
  (* implementation *)
end
Run Code Online (Sandbox Code Playgroud)

然后为了实际使用这些模块,我直接在一个名为的文件中定义了一个新模块prism.ml:

type state = value array
type t = state
type value =
  | VBOOL of bool
  | VINT of int
  | VFLOAT of float
  | VUNSET
(* all the functions required *)
Run Code Online (Sandbox Code Playgroud)

从第三个源(formulas.ml)我使用带有Prism模块的仿函数:

module PrismPctl = Pctl.Make(Prism)
open PrismPctl
Run Code Online (Sandbox Code Playgroud)

最后来自 main.ml

open Formulas.PrismPctl
(* code to prepare the object *)
PrismPctl.check_suite s.sys_state suite (* error here *)
Run Code Online (Sandbox Code Playgroud)

和compiles给出以下错误

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

根据我的理解,有一些名称的错误别名,它们是相同的(因为value array定义的类型t和它M with type s = P.t在仿函数中使用)但类型检查器不认为它们是相同的.

我真的不明白问题出在哪里,谁能帮助我?

提前致谢

Gil*_*il' 6

(你发布不可编辑的代码.这是一个坏主意,因为它可能会让人们更难以帮助你,因为将问题简化为一个简单的例子有时候足以解决它.但我认为无论如何我都会看到你的困难. )

在内部formulas.ml,Ocaml可以看到PrismPctl.s = Pctl.Make(Prism).t = Prism.t; 第一个相等是来自定义PrismPctl,第二个相等来自Pctl.Make(特别是with type s = P.t位)的签名.

如果您没有mli为其编写文件Formulas,则应编译代码.所以问题必须是.mli你写的文件没有提到正确的平等.你没有显示你的.mli文件(你应该,它们是问题的一部分),但大概是你写的

module PrismPctl : Pctl.M
Run Code Online (Sandbox Code Playgroud)

这是不够的:当编译器编译main.ml,它将不知道任何事情PrismPctl,这不是规定formulas.mli.您需要指定其中一个

module PrismPctl : Pctl.M with type s = Prism.t
Run Code Online (Sandbox Code Playgroud)

或者,假设您包含with type s = P.t在in的签名Makepctl.mli

module PrismPctl : Pctl.M with type s = Pctl.Make(Prism).s
Run Code Online (Sandbox Code Playgroud)