当我运行下面的代码时,我会得到一个语法错误,尽管据我所知,语法是正确的。这将尝试实现队列结构,其中函数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表示<-.但是我将一个适当类型的对象存储到一个可变字段中,所以我不知道出了什么问题。
发布于 2017-10-10 22:33:41
顶层语句由;;在OCaml中分隔.然而,;;在几个关键字(如let、open、type等)之前是可选的。这就是为什么大多数时候不需要;;的原因。
在您的示例中,需要;;来消除let y = {v = 2; next = None}和x.next <- Some y之间的歧义。后者是一个表达式,不以一个特殊的关键字开头,因此OCaml不知道在这里插入隐式;;。
另见Programs.html#-失踪-。
正如这里所解释的,你可以
let y = {v = 2; next = None}
;; x.next <- Some y或
let y = {v = 2; next = None}
let () = x.next <- Some y后一种解决方案之所以有效,是因为通过引入虚拟绑定,我们开始使用let语句,这再次消除了歧义。
注意:我还从代码中删除了尾随的;。;是将两个表达式组合在一起的实际上是一个infix运算符 (通过丢弃第一个表达式的结果并返回第二个表达式的结果)。这不是你想要的。
https://stackoverflow.com/questions/46676848
复制相似问题