OCAML将定义的类型与定义混淆?

时间:2017-03-31 01:42:55

标签: types ocaml typing as-pattern

我正在处理将正则表达式转换为NFA以及将NFA转换为OCAML中的DFA的作业。我一直在将我的代码编写在一个单独的文件中,以便测试每个"函数"单独使用,但是在使用as-pattern时遇到了一个问题。

NFA定义:

(* Imports not shown. *)

let sidx = ref 0
let new_state() = sidx := !sidx + 1; !sidx

type state = int
type states = state BatSet.t 
type delta = (state * alphabet, state BatSet.t) BatMap.t 
type e_delta = (state, state BatSet.t) BatMap.t
type final = state BatSet.t
type init = state

(* ... *)

type t = states * delta * e_delta * init * final 

(* create a new NFA with a single start state *)
let create_new_nfa () = 
   let is = new_state () in
      (BatSet.singleton is, BatMap.empty, BatMap.empty, is, BatSet.empty)

(* ... More Function(s) Not Shown.*)

当我自己编译下面的代码时(即我不使用make文件,而是手动输入编译命令输入),我没有问题,它的工作原理就像它假设的那样:

let regex2nfa : Regex.t -> Nfa.t
=fun regex ->
        let ((state, delta, e_delta, init, final) as nfa) = Nfa.create_new_nfa () in (*Line 9*)
        nfa

但是当我使用他们的make文件时,它抱怨说: enter image description here

这没有任何意义。 Nfa.t 的类型为:

  

' a *' b *' c *' d *' e

如声明所示:

type t = states * delta * e_delta * init * final

如果我拿出那个元组并且只是分配了名称" nfa "到 create_new_nfa 函数的输出,然后它编译得很好,但为什么这发生呢?

作为参考,可以找到make文件here

1 个答案:

答案 0 :(得分:7)

/etc/profileNfa.t中显示为abstract type,因此在nfa.mli模块之外,您不能认为它是5元组。你的Nfa - 模式就是这样,这就是被拒绝的原因。

(错误信息肯定会更有帮助。)

抽象类型是OCaml中的信息隐藏功能,它允许模块的作者阻止第三方代码依赖其实现的细节。

但是等等,为什么你的代码在顶层编译?我不确定,但我怀疑你做了as #use之类的事情,它会绕过nfa.ml并允许你对nfa.mli的内部做出假设类型。