2017-10-10 7 views
0

Lorsque j'exécute le code suivant, j'obtiens une erreur de syntaxe, bien que, pour autant que je sache, la syntaxe est correcte. Cela tente d'implémenter une structure de file d'attente, où la fonction from_list convertit une liste en file d'attente avec les valeurs correspondantes. J'ai écrit str_of_int_q pour imprimer le contenu d'une file d'attente. x et y sont supposés être deux nœuds, avec x en tête et y à la queue.Modification d'un champ mutable dans 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) 

Mon erreur:

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

ligne 32 est la ligne x.next <- Some y; et caractères 7-9 indiquent la <-. Mais je stocke dans un champ mutable un objet du type approprié, donc je ne vois pas ce qui ne va pas.

+0

Cela fonctionne-t-il si vous mettez ';;' avant 'x.next'? – melpomene

+0

@melpomene Huh, ça s'est passé quand j'ai mis ';;' avant 'x.next' et que j'ai enlevé'; 'de la fin. Je ne comprends pas exactement pourquoi cela fonctionne, mais c'est bien de voir que ça fonctionne. Mettez ceci comme une réponse et je l'accepterai. – Addem

Répondre

2

Les instructions de niveau supérieur sont séparées par ;; dans OCaml. Cependant, ;; est facultatif avant plusieurs mots-clés, tels que let, open, type, etc. C'est pourquoi vous n'avez pas besoin de ;; la plupart du temps.

Dans votre cas, ;; est nécessaire pour désambiguïser entre let y = {v = 2; next = None} et x.next <- Some y. Ce dernier est une expression et ne commence pas par un mot-clé spécial, donc OCaml ne sait pas insérer un ;; implicite ici.

Voir aussi http://ocaml.org/learn/tutorials/structure_of_ocaml_programs.html#The-disappearance-of.

Comme il expliqué, vous pouvez faire

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

ou

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

Cette dernière solution fonctionne car en introduisant un mannequin liant nous commençons notre déclaration avec let, qui disambiguates à nouveau.

Remarque: J'ai également supprimé le code ; de votre code. ; est actually an infix operator qui combine deux expressions (en jetant le résultat du premier et en renvoyant le résultat du second). Ce n'est pas ce que tu veux ici.