我对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

和以下仿函数:
module Make(P: ProbPA): (M with type s = P.t) = struct
  type s = P.t
  (* implementation *)
end

然后,为了实际使用这些模块,我直接在一个名为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 *)

从第三个来源(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 *)

并编译给出以下错误



从我的理解中,名称的别名有点不好,它们是相同的(因为value array是定义为t的类型,并且在仿函数中使用了M with type s = P.t),但是类型检查器并不认为它们是相同的。

我真的不明白问题出在哪里,有人可以帮助我吗?

提前致谢

最佳答案

(您发布了不可编译的代码。这是一个坏主意,因为它可能会使人们更难于帮助您,并且因为有时将您的问题简化为一个简单的示例就可以解决。但是我想无论如何我都会遇到您的困难。 )

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

这还不够:当编译器编译main.ml时,它不会知道PrismPctl中未指定的有关formulas.mli的任何信息。您需要指定
module PrismPctl : Pctl.M with type s = Prism.t

或者,假设您在with type s = P.tMake签名中包括了pctl.mli
module PrismPctl : Pctl.M with type s = Pctl.Make(Prism).s

关于module - 了解OCaml中的仿函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3327586/

10-11 03:28