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.
Warum verwenden Sie Google nicht, um ein Tutorial zu finden und es selbst zu tun? –
Ich kann das nicht finden. Kannst du mir einen Link geben? Bitte. Vielen Dank. –
[eine Google-Suche entfernt] (http://www.inf.ufsc.br/~jbosco/cleanBookI.pdf) –