解释器和.ml文件有什么区别?

时间:2018-09-20 15:17:12

标签: ocaml interpreter

我是Ocaml的新手,也正在使用口译员。我编写了不错的代码,可以很好地工作,但是问题是,相同的代码的行为因解释器和.ml文件而异。例如,我制作了一个模块,并使用其中的功能进行调试。但是,如果我写

let (n, queue) = IntListQ.deQ(IntListQ.enQ(IntListQ.enQ(IntListQ.emptyQ, [1;2;3]), [4;5])) in
        (n, queue)

在.ml文件中,它不会编译并显示语法错误。另一方面,如果我通过启动ocaml -init {filename} .ml在解释器中编写表达式,则它可以工作。那是什么问题呢?为什么相同的表达式在.ml文件和解释器中表现不同?

详细说明整个代码,如下所示:

type heap = EMPTY of rank | NODE of rank * value * heap * heap
and rank =int
and value=int

exception EmptyHeap

let rank : heap -> rank = fun i ->
    match i with
    | EMPTY _ -> -1
    | NODE (r, _, _ ,_) -> r

(****print heap expression****)

module type Queue =  
    sig
        type element
        type queue
        exception EMPTY_Q
        val emptyQ: queue
        val enQ: queue * element -> queue
        val deQ: queue -> element * queue   
        val isempty : queue -> bool
    end

module IntListQ  = 
    struct
        type element = heap
        type queue = heap list * heap list(*element list??*)
        exception EMPTY_Q

        let emptyQ : heap list * heap list = ([],[])

        let enQ: (heap list * heap  list) * heap ->  heap  list * heap  list = fun (que , ele)->
            let (first, second) = que in
            let new_second = List.append second (List.rev first) in
            (ele::[] ,new_second)

        let deQ: (heap  list * heap  list) -> heap * (heap list * heap  list) = fun que ->
        match que with
        | ([], []) -> raise EMPTY_Q
        | _ ->
            let (first, second) = que in
            let new_second = List.append second (List.rev first) in
            let out = List.hd new_second in
            (out, ([],List.tl new_second))

        let isemtpy: heap list * heap list -> bool = fun i ->
            match i with
            | ([], []) -> true
            | _ -> false
    end

let printhpst : heap -> unit = fun x ->
    let startq = ref IntListQ.emptyQ    
    startq := IntListQ.enQ !startq (EMPTY -1)
    let tim = ref false in
        while  !tim do
            let n = startq.deQ
            printhp n;
            match n with
            | NODE (i, j, k, l) -> 
            begin
                startq := IntListQ.enQ !startq k
                startq := IntListQ.enQ !startq l
            end
            | EMPTY 0-> ()
            | EMPTY -1 -> startq := IntListQ.enQ !startq EMPTY -1

            tim := IntListQ.isempty startq
        done

let printhp : heap -> unit = fun hp ->
    match hp with
    |EMPTY  _ -> print_endline "EMPTY";
    |NODE (i, j, k, l) -> (print_endline ("( "^(string_of_int i)^" , "^(string_of_int j)^" , "^(string_of_int (rank k))^" , "^(string_of_int (rank l))^" )"););;

let findMin h = 
    (match h with
    | EMPTY _ -> raise EmptyHeap
    | (NODE(_,x,_,_)) -> x);;

let shake (x, lh, rh) = 
    print_endline "shake";
    if(rank lh) >= (rank rh)
    then NODE(rank rh+1, x, lh, rh)
    else NODE(rank lh+1, x, rh, lh)

let rec merge : heap * heap -> heap = fun (lh, rh)->
    match (lh, rh) with
    | ( EMPTY _ , EMPTY _ ) -> print_endline "merge: EMPTY Empty"; printhp lh; printhp rh; print_endline "_____________________";EMPTY 0
    | ( EMPTY _, NODE (i, j, k, l) )
    | (NODE (i, j, k, l), EMPTY _ ) -> print_endline "merge:NODE"; printhp lh; printhp rh; print_endline "_____________________"; NODE ( i, j, k, l )
    | (NODE _, NODE _ )->
        print_endline "merge:NODE NODE";
        printhp lh;
        printhp rh;
        print_endline "_____________________";
        let minlh = findMin lh in
        let minrh = findMin rh in

        if minlh<=minrh then 

            (print_endline "minlh<=minrh";
            print_endline "_____________________";
            let dellh = deleteMin lh in
            shake (minlh, dellh, rh))

        else
            (print_endline "minlh>minrh";
            print_endline "_____________________";
            let delrh= deleteMin rh in
            shake (minrh, delrh, lh))

and insert : rank*heap -> heap = fun (x, h )->
    merge(h, NODE( 0, x, EMPTY 0, EMPTY 0))

and deleteMin h = 
    print_endline "deleteMin";
    printhp h;
    print_endline "_____________________";
    match h with
    | EMPTY _ -> raise EmptyHeap
    | NODE(_, x , lh, rh) -> merge (lh, rh)

(* try basic 
  let heap1 = NODE(0, 2, EMPTY, EMPTY) in
  let heap2 = NODE(0, 3, EMPTY, EMPTY) in
  findMin(merge (heap1, heap2));;
   *)

1 个答案:

答案 0 :(得分:1)

要获得有用的答案,您需要提供更多详细信息,包括IntListQ的定义。

如果解释器(OCaml顶级)和编译器(ocamlc / ocamlopt)不同意该语言,那么到现在可能已经注意到了。

解释器出现意外行为的最常见原因是,加载文件时,解释器中存在一些现有定义。如果您尝试从头开始重新启动解释器进行测试,则可能会看到更一致的行为。