【问题标题】:OCAML confuses defined type with definition?OCAML 将定义类型与定义混淆?
【发布时间】:2017-03-31 01:42:55
【问题描述】:

我正在处理一项将正则表达式转换为 NFA 以及在 OCAML 中将 NFA 转换为 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文件可以在here找到

【问题讨论】:

    标签: types ocaml typing as-pattern


    【解决方案1】:

    Nfa.tnfa.mli 中作为abstract type 公开,因此在Nfa 模块之外,您不能假定它是一个5 元组。您的 as-pattern 正是这样做的,这就是它被拒绝的原因。

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

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

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

    【讨论】:

    • 附带说明,使 OP 的代码更清晰(恕我直言)的一种方法是将 Nfa.t 定义为记录而不是元组。
    • @RichouHunter 这是我的家庭作业,所以我无法控制修改 NFA 代码。我必须与它进行交互并相应地将其用于不同的任务。但是感谢您的注意,如果我将来创建任何类型,我会查看记录,例如。
    • @DanHoynoski,告诉你的老师他们可以让他们的代码变得更好! :P
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    相关资源
    最近更新 更多