2012-04-16 16 views
11

Ein übliches Muster für CLI-Anwendungen besteht darin, in einer Endlosschleife zu laufen, bis der Benutzer einen Befehl zum Beenden eingibt. Wie, in C-Sprache:Unendliche Hauptschleife in F #

while(1){ 
scanf("%c", &op); 
    ... 
    else if(op == "q") 
     break; 
    } 

Was würde in Fis das Muster für eine solche Konsolenanwendung sein (versucht Schwanz recursrion zu verwenden, aber nicht)?

Antwort

10

Typing in Browser kann somit Fehler enthalten:

let rec main() = 
    let c = System.Console.ReadKey() 
    if c.Key = System.ConsoleKey.Q then() // TODO: cleanup and exit 
    else 
    // TODO: do something in main 
    main() 
+4

Überläuft dies den Stack, wenn die Tail-Rekursion nicht aktiviert ist? – Maslow

3

Auch

while true do 
    (* ..code.. *) 

Aber ich denke, Schwanz-Rekursion ist mehr Phantasie (sie beide unter --optimize auf die gleiche Sache zusammenstellen werde) .

5

Eine solche Funktion kann nützlich sein:

let rec forever f = 
    f() 
    forever f 

Verbrauch:

forever <| fun() -> 
    //function body 

Eine wörtliche Übersetzung des Codes, jedoch wäre:

while true do 
    //body 
+0

Schöne Syntax, aber nicht sehr praktisch, wenn Sie eine Ausgangsbedingung wollen, würde ich sagen. –

9

Hier ist eine keine blockierende Version, die auf den einzelnen Tastendruck reagiert.

open System 

let rec main() = 
    // run code here 

    // you may want to sleep to prevent 100% CPU usage 
    // Threading.Thread.Sleep(1); 

    if Console.KeyAvailable then 
     match Console.ReadKey().Key with 
     | ConsoleKey.Q ->() 
     | _ -> main() 
    else 
     main() 

main() 
+0

Kann ein 'Sleep (0)' oder 'SwitchToThread()' in der 'else' oder das wird eine hohe CPU-Auslastung Schleife sein. : -] – ildjarn

+0

Burn Baby brennen! Guter Punkt obwohl. :) – gradbot

+0

+1, ich mochte dieses! Sehr cool. – yamen