typesocamltypingas-pattern

OCAML confuses defined type with definition?


I am working on an assignment for converting Regular Expressions into an NFA and for converting an NFA to DFA in OCAML. I have been writing my code in a separate file in order to test each "function" individually, but I have come across a problem when using the as-pattern.

NFA Definition:

(* 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.*)

When I compile the code below on its own (i.e. I don't use a make file, but rather type the compile command input manually), I have no problem and it works just like how it is suppose too:

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

But when I use their make file, it complains by saying the following: enter image description here

This doesn't make any sense. Nfa.t is of type:

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

as shown with its declaration of:

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

If I take out that tuple and just assigned the name "nfa" to the output of the create_new_nfa function, then it compiles just fine, but why on earth is this happening?

For reference, the make file can be found here


Solution

  • Nfa.t is exposed as an abstract type in nfa.mli, so outside of the Nfa module you are not permitted to assume that it is a 5-tuple. Your as-pattern does exactly that, which is why it is rejected.

    (The error message could definitely be more helpful.)

    Abstract types are an information hiding feature in OCaml that allows the author of a module to prevent details of their implementation being relied on by third party code.

    But wait, why does your code compile in the toplevel? I'm not certain, but I suspect that you did something like #useing nfa.ml, which would bypass nfa.mli and allow you to make assumptions about the internals of the Nfa.t type.