2017-11-06 16 views
1

Ich habe diese Mergesort-Implementierung geschrieben, die funktioniert, wenn ich die Divide-Funktion außerhalb der Mergesort-Funktion setzen. Aber wenn ich versuche, eine innere Funktion von mergesort zu teilen, stoße ich auf einen Syntaxfehler.OCaml: und Schlüsselwort Syntaxfehler

Ich weiß, es muss eine wirklich einfache Erklärung dafür geben. Ich habe überall im Internet nachgeschaut, aber nichts gefunden. Hier

ist der Code:

let mergesort list = 
    let rec sort lists acc = (
    let rec merge sublist1 sublist2 merged_list = 
    match sublist1 with 
     |[] -> merged_list @ sublist2 
     |hd1 :: tl1 -> 
     match sublist2 with 
      |[] -> merged_list @ sublist1 
      |hd2 :: tl2 -> 
      if hd1 < hd2 then merge tl1 sublist2 (merged_list @ hd1::[]) 
      else merge sublist1 tl2 (merged_list @ hd2::[]) 
    in match lists with 
     |[] -> 
     (match acc with 
      |[] -> [] 
      |hd :: [] -> hd 
      |_ -> sort acc []) 
     |hd :: tl -> sort (List.tl tl) ((merge (List.hd tl) hd [])::acc) 
) 
    and rec divide list list_of_lists = (
    match list with 
     [] -> list_of_lists 
     |hd :: tl -> divide tl ((hd :: []) :: list_of_lists) 
) 
    in sort (divide list []) [] 
;; 

und es ergibt sich in:

Characters 567-570: 
and rec divide list list_of_lists = (
    ^^^ 
Error: Syntax error 
+0

Haben Sie versucht, das Schlüsselwort 'rec' zu entfernen, das Ihnen der Fehler sagt? 'und' wird die vorherige Definition wiederholen, die in diesem Fall 'let rec' ist, also schreiben Sie effektiv' let rec rec' –

Antwort

1

Sie müssen einfach die rec Keyword aus Ihrer Definition entfernen es.

Dies ist, weil Sie, wenn Sie das and-Schlüsselwort verwenden, Sie die vorherige Definition syntaktisch wiederholen, in diesem Fall let rec.

So Ihre aktuelle Implementierung ist das Gleiche wie zu sagen let rec rec

+0

, wenn Sie das 'and' Schlüsselwort verwenden, wiederholen Sie nicht die vorherige Definition. – ivg

+0

@ivg was macht es dann genau? –

+0

Es ist nur eine Syntax (eine Notation), die mehrere Definitionen trennt. Es handelt sich nicht wirklich um die Rekursivität, z. B. "let x = y und y = x in Ausdruck" ist keine rekursive Definition, und es bindet zwei Variablen in "Ausdruck". Vgl. Mit "let x = y in let y = x in Ausdruck" – ivg

2

A local definition hat die folgende Syntax in OCaml:

let [rec] pattern1 = expr1 and … and patternN = exprN in expr 

So ein extra rec nach dem and Schlüsselwort nicht zulässig ist, und erlaubt ist erst nach dem ersten let. Das Flag rec erweitert sich auf alle Werte, die in der lokalen Definition definiert sind. Daher müssen Sie nur dieses fehlerhafte rec nach and entfernen.