2

我正在从事一项将正则表达式转换为 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 文件时,它会抱怨以下内容: 在此处输入图像描述

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

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

如其声明所示:

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

如果我取出那个元组并将名称“ nfa ”分配给create_new_nfa函数的输出,那么它编译得很好,但到底为什么会发生这种情况呢?

作为参考,make 文件可以在这里找到

4

1 回答 1

7

Nfa.t在中作为抽象类型nfa.mli公开,因此在Nfa模块之外,您不得假设它是 5 元组。您的as-pattern 正是这样做的,这就是它被拒绝的原因。

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

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

但是等等,为什么你的代码在顶层编译?我不确定,但我怀疑你做了类似#useing的事情nfa.ml,这会绕过nfa.mli并允许你对Nfa.t类型的内部进行假设。

于 2017-03-31T03:06:09.003 回答