2016-07-03 6 views
1

Ich versuche, eine einfache Funktion zu erstellen, die Ausgabe in eine Datei schreiben kann, sagen wir file.txt. Die Ausgabe ist eine Multiplikationstabelle (wie unten zu sehen).Mit OCaml eine einfache Multiplikationstabelle ausgeben

Beispiel der Multiplikationstabelle, wenn das Funktionsargument 5: Example of the multiplication table if the function argument is 5

Das Problem ist, dass OCaml hängt nur, wenn ich den Code ausführen (wahrscheinlich wegen einer unendlichen Rekursion?). Ich halte Blick durch die Logik und es scheint okay ..

(*n is the row counter and n2 is the column counter*) 
let rec row ch x n = 
    let rec column ch x n n2 = 
     (*If column counter reaches limit then stop here*) 
     if (n2 = x+1) 
     then() 
     else 
      output_string ch (string_of_int (n2*n)); 
      output_char ch '\t'; 
      column ch x n (n2+1) 
    in 
     column ch x n 1; 

     (*If row counter reaches limit then stop here*) 
     if n = x+1 
     then() 
     else 
      output_char ch '\n'; 
      row ch x (n+1);; 

Später Zeile in der Tabelle Funktion wie diese nenne ich:

let rec table file x = 
    let ch = open_out file in 
     row ch x 1; 
     close_out ch;; 

Als ich table "foo" 5 laufen, sondern hängt. Wie kann ich in Zukunft besser mit Fehlern umgehen? Empfohlene Debugging-Optionen für OCaml?

Antwort

3

Sie haben zwei Fälle mit demselben Problem: Der else-Teil von if/then/else steuert nur einen Ausdruck, aber Sie erwarten, dass er mehrere Ausdrücke steuert.

Im ersten Fall steuert die else nur die output_string. Dies bedeutet, dass der Rest der column-Funktion in allen Fällen ausgeführt wird. Dies ist tatsächlich eine unendliche Rekursion.

Im zweiten Fall steuert die else nur die output_char. Auch dies gibt Ihnen eine unendliche Rekursion.

Sie können dieses Problem beheben, indem begin/end hier hinzufügen:

begin 
output_string ch (string_of_int (n2*n)); 
output_char ch '\t'; 
column ch x n (n2+1) 
end 

Und hier:

begin 
output_char ch '\n'; row ch x (n+1) 
end 

Nachdem ich diese Änderungen vornehmen, funktioniert der Code für mich.

+0

Danke für die Antwort! Arbeitete auch für mich. Steuert sonst nur der Druckausdruck unmittelbar danach aufgrund des Semikolonoperators? (der Operator, wenn ich mich richtig erinnere, verwirft den Ausdruck auf der linken Seite) –

+0

Ja, eine andere Möglichkeit, es zu betrachten ist, dass 'dann' und' else' höhere Priorität haben als ';'. Sie können mehrere Ausdrücke auf andere Arten kombinieren, die nicht den Beginn/das Ende erfordern. –