, bölüm 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.
Somut olarak, normalde Arity 0 sahiptir Start
, yapabilir *World
den *World
bir fonksiyon (argümansızdır). Buradaki fikir şu ki, dünyayı değiştiren bir fonksiyona sahip olduğumuzdur, bu da yan etkilere izin verildiği anlamına gelir (artık gerçek yan etkiler değil, dünyadaki operasyonlar).
*
World
Çeşidi tekliği gösterir. Bu, dünya argümanının iki örneğine sahip olamayacağınız anlamına gelir.
Start :: *World -> *(*World, *World)
Start w = (w, w)
standart IO kullanmak için, StdEnv
içinde StdFile
modülünden fonksiyonları gerekir: Örneğin, aşağıdaki derleme zamanlı benzersizliği hata verecektir. Eğer ihtiyacımız olacak işlevler şunlardır:
stdio :: !*World -> *(!*File, !*World)
fclose :: !*File !*World -> !(!Bool, !*World)
Ben tipleri biraz basitleştirilmiş, aslında sınıfta
FileSystem
geliyoruz.
stdio
, bir dünyadan bir
benzersiz
File
açar ve ayrıca yeni, değiştirilmiş dünyayı döndürür.
fclose
bir dünyadaki bir dosyayı kapatır ve bir başarı bayrağı ve değiştirilen dünyayı döndürür.
Sonra okumak ve o stdion dosyasından yazmak için, şunları kullanabilirsiniz:
freadline :: !*File -> *(!*String, !*File)
fwrites :: !String !*File -> !*File
freadline
satır karakteri içeren bir dize, bir satır okur. fwrites
bir dosyaya bir dize yazar, genellikle stdio'ya yazarken bir satırsonu karakteri eklemek istersiniz.
Bir araya getirmek:
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
#
sözdizimi sizin için yeni olabilir.
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
Artık kullanarak pseudocode istediğini yapmak mümkün olmalıdır: Bu kullanmaktan daha uygundur dosyaların (ya da diğer şeylerin) için aynı adı kullanmasına izin verir let
bir tür, örneğin vargirilene kadar kendini çağıran bir yardımcı işlevi olan loop :: *File -> *File
.
Sadece freadline
ve fwrites
'dan daha fazla işlev var, bir fikir için bkz. StdFile.dcl
.
Neden bir öğretici bulmak ve kendiniz yapmak için google'ı kullanmıyorsunuz? –
Bunu bulamıyorum. bana bir bağlantı verebilir misin? Lütfen. Teşekkürler. –
[bir google arama] (http://www.inf.ufsc.br/~jbosco/cleanBookI.pdf) –