2017-10-10 42 views
0

当我运行以下代码时,出现语法错误,但据我所知,语法是正确的。这将尝试实现队列结构,其中函数from_list将列表转换为具有相应值的队列。我写了str_of_int_q来打印队列的内容。 xy应该是两个节点,头部为x,尾部为y更改OCaml中的可变字段

;; 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) 

我的错误:32

line 32, characters 7-9: 
Error: Syntax error 

行是行x.next <- Some y;和字符7-9指示<-。但是我将一个适当类型的对象存储到一个可变字段中,所以我没有看到发生了什么问题。

+0

如果你把';;'放在'x.next'之前,它会起作用吗? – melpomene

+0

@melpomene呃,当我把';;'放在'x.next'之前,然后把';'从结尾处拿出来的时候。我不明白为什么会这样,但很高兴看到它的确如此。把这个作为答案,我会接受它。 – Addem

回答

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,再次做歧义消除

let y = {v = 2; next = None} 
;; x.next <- Some y 

let y = {v = 2; next = None} 
let() = x.next <- Some y 

这后一种解决方案工作。

注意:我也从代码中删除了尾随的;;actually an infix operator,它组合了两个表达式(通过抛出第一个表达式的结果并返回第二个表达式的结果)。这不是你想要的。