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



我是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));;
*)

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

如果解释器(OCaml顶级(和编译器(ocamlc/ocamlopt(在语言上存在分歧,那么现在可能已经注意到了这一点。

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

最新更新