在OCaml中更改可变字段

时间:2017-10-10 22:14:36

标签: syntax-error ocaml

当我运行以下代码时,我得到一个语法错误,尽管我可以告诉语法是正确的。这会尝试实现队列结构,其中函数from_list将列表转换为具有相应值的队列。我写了str_of_int_q来打印队列的内容。 xy应该是两个节点,头部为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表示<-。但是我在一个可变字段中存储了一个相应类型的对象,所以我看不出有什么问题。

1 个答案:

答案 0 :(得分:2)

在OCaml中,顶级语句由;;分隔。但是,;;在多个关键字之前是可选的,例如letopentype等。这就是您不需要;;的原因大多数时候。

在您的情况下,需要;;来消除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,它结合了两个表达式(通过抛弃第一个结果并返回第二个结果)。这不是你想要的。