2017-10-10 3 views
0

Wenn ich den folgenden Code ausführen, erhalte ich einen Syntaxfehler, obwohl, soweit ich feststellen kann, die Syntax korrekt ist. Dies versucht eine Warteschlangenstruktur zu implementieren, bei der die Funktion from_list eine Liste in eine Warteschlange mit den entsprechenden Werten konvertiert. Ich schrieb str_of_int_q, um den Inhalt einer Warteschlange zu drucken. x und y sollen zwei Knoten sein, mit x am Kopf und y am Ende.Ändern eines veränderbaren Felds in 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) 

Mein Fehler:

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

32 Linie ist die Linie x.next <- Some y; und Zeichen 7-9 der <- anzuzeigen. Aber ich speichere ein Objekt des passenden Typs in ein veränderbares Feld, damit ich nicht sehe, was falsch läuft.

+0

Funktioniert es, wenn Sie '' '' vor 'x.next' setzen? – melpomene

+0

@melpomene Huh, es tat, als ich '' '' vor 'x.next' legte und dann' '' vom Ende nahm. Ich verstehe nicht genau, warum das funktioniert, aber es ist großartig zu sehen, dass es funktioniert. Setzen Sie das als Antwort und ich werde es akzeptieren. – Addem

Antwort

2

Anweisungen auf oberster Ebene sind durch ;; in OCaml getrennt. Jedoch ist ;; optional vor mehreren Schlüsselwörtern, wie let, open, type, etc. Das ist der Grund, warum Sie die meiste Zeit ;; nicht benötigen.

In Ihrem Fall wird ;; benötigt, um zwischen let y = {v = 2; next = None} und x.next <- Some y zu disambiguieren. Letzteres ist ein Ausdruck und beginnt nicht mit einem speziellen Schlüsselwort, daher weiß OCaml nicht, hier ein implizites ;; einzufügen.

Siehe auch http://ocaml.org/learn/tutorials/structure_of_ocaml_programs.html#The-disappearance-of.

Wie erklärt es, Sie entweder

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

oder

tun kann, weil durch eine Dummy-Einführung Bindung wir beginnen unsere Erklärung mit let, die wiederum disambiguiert
let y = {v = 2; next = None} 
let() = x.next <- Some y 

Diese letztere Lösung funktioniert.

Hinweis: Ich habe auch die nachfolgenden ; aus Ihrem Code entfernt. ; ist actually an infix operator, das zwei Ausdrücke kombiniert (indem das Ergebnis des ersten weggeworfen wird und das Ergebnis des zweiten zurückgegeben wird). Das ist nicht was du willst.

Verwandte Themen