0

Wie macht man das in Clean?Wie liest man von stdin?

Pseudo-Code:

loop: 
    input = read_stdin 
    if input == "q": 
     break loop 
    else: 
     print "you input: ", input 

Eigentlich habe ich einen Blick auf einige pdf hatte. Aber ich habe eine Vorstellungskraft, es ist schwierig, mit stdin und stdout umzugehen. Könnte ich ein Codebeispiel haben, um stdio zu verwenden?

Nach Keelans Anweisungen hatte ich mein kleines Programm beendet.

module std_in_out_loop 
import StdEnv 

loop :: *File -> *File 
loop io 
# io = fwrites "input your name: " io 
# (name, io) = freadline io 
# name = name % (0, size name - 2) 
| name == "q" 
# io = fwrites "Bye!\n" io 
= io 
| name == "" 
# io = fwrites "What's your name?\n" io 
= loop io 
| otherwise 
# io = fwrites ("hello " +++ name +++ "\n") io 
= loop io 

Start:: *World -> *World 
Start world 
# (io, world) = stdio world 
# io = loop io 
# (ok, world) = fclose io world 
| not ok = abort "Cannot close io.\n" 
| otherwise = world 
+0

Warum verwenden Sie Google nicht, um ein Tutorial zu finden und es selbst zu tun? –

+0

Ich kann das nicht finden. Kannst du mir einen Link geben? Bitte. Vielen Dank. –

+0

[eine Google-Suche entfernt] (http://www.inf.ufsc.br/~jbosco/cleanBookI.pdf) –

Antwort

0

Vom Clean 2.2 manual, Kapitel 9:

Although Clean is purely functional, operations with side-effects (I/O operations, for instance) are permitted. To achieve this without violating the semantics, the classical types are supplied with so called uniqueness attributes. If an argument of a function is indicated as unique, it is guaranteed that at run-time the corresponding actual object is local, i.e. there are no other references to it. Clearly, a destructive update of such a “unique object” can be performed safely.

Konkret können Sie Start machen, die normalerweise arity hat 0 (keine Argumente), eine Funktion *World-*World. Die Idee ist, dass wir jetzt eine Funktion haben, die die Welt verändert, was bedeutet, dass Nebenwirkungen erlaubt sind (sie sind keine wirklichen Nebenwirkungen mehr, sondern Operationen auf der Welt).

Die * gibt die Eindeutigkeit der World Art an. Das bedeutet, dass Sie niemals zwei Instanzen des world-Arguments haben können. Zum Beispiel wird im Folgenden einem Kompilierung-Fehler Einzigartigkeit geben:

Start :: *World -> *(*World, *World) 
Start w = (w, w) 

Standard-IO zu verwenden, werden Sie in StdEnv Funktionen aus dem StdFile Modul benötigen. Die Funktionen Sie gehen zu müssen, sind:

stdio :: !*World -> *(!*File, !*World) 
fclose :: !*File !*World -> !(!Bool, !*World) 

ich die Typen ein wenig vereinfacht, sie sind tatsächlich aus der Klasse FileSystem. stdio öffnet eine einzigartigeFile aus einer Welt und gibt auch die neue, veränderte Welt zurück. fclose schließt eine Datei in einer Welt und gibt ein Erfolgsflag und die modifizierte Welt zurück.

Dann zu lesen und aus dieser stdio Datei zu schreiben, können Sie verwenden:

freadline :: !*File -> *(!*String, !*File) 
fwrites :: !String !*File -> !*File 

freadline liest eine Zeile in einen String, der Newline-Zeichen enthält. fwrites schreibt eine Zeichenfolge in eine Datei, normalerweise möchten Sie beim Schreiben in stdio ein Zeilenumbruchzeichen einfügen.

Putting es zusammen:

Start :: *World -> *World 
Start w 
# (io,w) = stdio w        // open stdio 
# io = fwrites "What is your name?\n" io   // ask for name 
# (name,io) = freadline io      // read in name 
# name = name % (0, size name - 2)    // remove \n from name 
# io = fwrites ("Hello, " +++ name +++ "!\n") io // greet user 
# (ok,w) = fclose io w       // close stdio 
| not ok = abort "Couldn't close stdio"   // abort in case of failure 
= w            // return world from Start 

Die # Syntax könnte neu für Sie. Es ist eine Art von let, die Sie den gleichen Namen für Dateien (oder andere Dinge) zu verwenden, ermöglicht es, die bequemer ist als die Verwendung von, zum Beispiel:

Start w = w3 
where 
    (io, w1) = stdio w 
    io1 = fwrites "What is your name?\n" io 
    (name, io2) = freadline io1 
    //... 
    (ok, w3) = fclose io10 w2 

Jetzt sollten Sie in der Lage sein zu tun, was Sie in Pseudo-Code verwenden möchten eine Hilfsfunktion loop :: *File -> *File, die sich rekursiv aufruft, bis q eingegeben wird.

Es gibt mehr Funktionen als nur freadline und fwrites, siehe StdFile.dcl für eine Idee.

+0

Hallo, Camil, ich bin froh, Sie wiederzusehen. Würden Sie bitte? Gib mir eine ICL-Datei? Das entspricht dem Pseudocode. Lass mich damit spielen? Und dann komme ich zurück, um deine Anweisungen zu lesen. Es kann dumm sein? Ich weiß es nicht? Bitte. Vielen Dank! –

+0

@sama das Ding nach dem "Zusammensetzen" ist ein fertiges Beispiel, fügen Sie einfach einen Modulkopf hinzu und 'importieren StdEnv'. Versuchen Sie, 'loop :: * Datei -> * Datei 'selbst zu schreiben, wie ich im letzten Absatz vorgeschlagen habe. Wenn Sie es nicht schaffen, stellen Sie bitte eine neue Frage mit Ihrem Code und einer konkreten Frage. Vielen Dank! – Keelan

+0

Hallo, Camil! Danke noch einmal. Für mich? CLEAN ist ganz anders, ** Start ** ist die einzige Chance, etwas auszugeben? (andere Sprache kann das überall tun. Beispiel, für Python? Wenn Yoy etwas lesen oder etwas ausgeben möchte? Es ist sehr einfach. Ich kann das googlen und schreibe etwas Code für mich selbst) Aber, es ist schwierig für mich. Tut mir leid, ich habe keine Ahnung, sie in eine icl-Datei zu gruppieren. –