当我运行以下代码时,我得到一个语法错误,尽管我可以告诉语法是正确的。这会尝试实现队列结构,其中函数from_list
将列表转换为具有相应值的队列。我写了str_of_int_q
来打印队列的内容。 x
和y
应该是两个节点,头部为x
,尾部为y
。
;; open Assert
type 'a qnode = {v: 'a;
mutable next: 'a qnode option}
type 'a queue = {mutable head: 'a qnode option;
mutable tail: 'a qnode option}
let from_list (l: 'a list) : 'a queue =
let rec loop (l2: 'a list) (qu: 'a queue) =
begin match l2 with
| [] -> qu
| [x] -> let y = {v = x; next = None} in
qu.head <- Some y; qu.tail <- Some y;
qu
| h1::h2::t -> let y = qu.head in
let z = {v = h1; next = y} in
qu.head <- Some z;
qu
end
in loop l {head = None; tail = None}
let str_of_int_q (q: int queue) : string =
let rec loop (r: int qnode option) (s: string) : string =
begin match r with
| None -> s
| Some n -> loop n.next (s ^ (string_of_int n.v))
end
in loop q.head ""
let x = {v = 1; next = None}
let y = {v = 2; next = None}
x.next <- Some y;
let z = {head = Some x; tail = Some y}
;; print_endline (str_of_int_q z)
我的错误:
line 32, characters 7-9:
Error: Syntax error
第32行是行x.next <- Some y;
,字符7-9表示<-
。但是我在一个可变字段中存储了一个相应类型的对象,所以我看不出有什么问题。
答案 0 :(得分:2)
在OCaml中,顶级语句由;;
分隔。但是,;;
在多个关键字之前是可选的,例如let
,open
,type
等。这就是您不需要;;
的原因大多数时候。
在您的情况下,需要;;
来消除let y = {v = 2; next = None}
和x.next <- Some y
之间的歧义。后者是一个表达式,并不是以特殊关键字开头的,因此OCaml不知道在这里插入隐式;;
。
另见http://ocaml.org/learn/tutorials/structure_of_ocaml_programs.html#The-disappearance-of。
正如那里所解释的,你可以做到
let y = {v = 2; next = None}
;; x.next <- Some y
或
let y = {v = 2; next = None}
let () = x.next <- Some y
后一种解决方案有效,因为通过引入虚拟绑定,我们用let
开始我们的声明,这再次消除了歧义。
注意:我还从您的代码中删除了跟踪;
。 ;
是actually an infix operator,它结合了两个表达式(通过抛弃第一个结果并返回第二个结果)。这不是你想要的。