Кіріспе
Компьютерде бірегей тип объектінің бір ғана жіпте қолданылуын және оған ең көп дегенде бір сілтеме болуын қамтамасыз етеді. Егер мәннің бірегей түрі болса, оған қолданылатын функция объектінің машиналық кодын тікелей жаңарту арқылы оңтайландырылуы мүмкін. Мұндай тікелей жаңартулар функционалдық тілдердің тиімділігін арттырып, референциялық ашықтықты сақтайды. Бірегей типтер функционалдық және императивті бағдарламалауды интеграциялау үшін де қолданылуы мүмкін.
Кіріспе
Бірегейлік типтеуді мысалмен түсіндіруге болады. ReadLine функциясы берілген файлдың келесі мәтін жолын оқиды:
function readLine(File f) returns String
return line where
String line = doImperativeReadLineSystemCall(f)
end
end
Now doImperativeReadLineSystemCall reads the next line from the file using an OS level system call which has the side effect of changing the current position in the file. But this violates referential transparency because calling it multiple times with the same argument will return different results each time as the current position in the file gets moved. This in turn makes readLine violate referential transparency because it calls doImperativeReadLineSystemCall. However, using uniqueness typing, we can construct a new version of readLine that is referentially transparent even though it's built on top of a function that's not referentially transparent:
function readLine2(unique File f) returns (unique File, String)
return (differentF, line) where
String line = doImperativeReadLineSystemCall(f)
File differentF = newFileFromExistingFile(f)
end
end
The unique declaration specifies that the type of f is unique; that is to say that f may never be referred to again by the caller of readLine2 after readLine2 returns, and this restriction is enforced by the type system. And since readLine2 does not return f itself but rather a new, different file object differentF, this means that it's impossible for readLine2 to be called with f as an argument ever again, thus preserving referential transparency while allowing for side effects to occur.
функция readLine(File f) қайтарады String
return line where
String line = doImperativeReadLineSystemCall(f)
end
end
function readLine(File f) returns String
return line where
String line = doImperativeReadLineSystemCall(f)
end
end
Now doImperativeReadLineSystemCall reads the next line from the file using an OS level system call which has the side effect of changing the current position in the file. But this violates referential transparency because calling it multiple times with the same argument will return different results each time as the current position in the file gets moved. This in turn makes readLine violate referential transparency because it calls doImperativeReadLineSystemCall. However, using uniqueness typing, we can construct a new version of readLine that is referentially transparent even though it's built on top of a function that's not referentially transparent:
function readLine2(unique File f) returns (unique File, String)
return (differentF, line) where
String line = doImperativeReadLineSystemCall(f)
File differentF = newFileFromExistingFile(f)
end
end
The unique declaration specifies that the type of f is unique; that is to say that f may never be referred to again by the caller of readLine2 after readLine2 returns, and this restriction is enforced by the type system. And since readLine2 does not return f itself but rather a new, different file object differentF, this means that it's impossible for readLine2 to be called with f as an argument ever again, thus preserving referential transparency while allowing for side effects to occur.
Енді doImperativeReadLineSystemCall файлдың келесі жолын операциялық жүйе деңгейіндегі жүйелік шақыру арқылы оқиды, бұл файлдың ағымдағы орнын өзгертудің жанама әсерін тудырады. Бірақ бұл сілтемелік ашықтықты бұзады, өйткені оны бірнеше рет бірдей аргументпен шақыру әрқашан әртүрлі нәтиже береді, себебі файлдың ағымдағы орны жылжытылады. Бұл өз кезегінде readLine функциясының сілтемелік ашықтықты бұзуына себеп болады, өйткені ол doImperativeReadLineSystemCall функциясын шақырады. Алайда, бірегейлік типтеуді пайдаланып, readLine функциясының жаңа нұсқасын құрастыруға болады, ол сілтемелік ашықтықты сақтайды, тіпті ол сілтемелік ашықтығы жоқ функцияның үстінде салынған болса да:
function readLine(File f) returns String
return line where
String line = doImperativeReadLineSystemCall(f)
end
end
Now doImperativeReadLineSystemCall reads the next line from the file using an OS level system call which has the side effect of changing the current position in the file. But this violates referential transparency because calling it multiple times with the same argument will return different results each time as the current position in the file gets moved. This in turn makes readLine violate referential transparency because it calls doImperativeReadLineSystemCall. However, using uniqueness typing, we can construct a new version of readLine that is referentially transparent even though it's built on top of a function that's not referentially transparent:
function readLine2(unique File f) returns (unique File, String)
return (differentF, line) where
String line = doImperativeReadLineSystemCall(f)
File differentF = newFileFromExistingFile(f)
end
end
The unique declaration specifies that the type of f is unique; that is to say that f may never be referred to again by the caller of readLine2 after readLine2 returns, and this restriction is enforced by the type system. And since readLine2 does not return f itself but rather a new, different file object differentF, this means that it's impossible for readLine2 to be called with f as an argument ever again, thus preserving referential transparency while allowing for side effects to occur.
функция readLine2(unique File f) қайтарады (unique File, String)
return (differentF, line) where
String line = doImperativeReadLineSystemCall(f)
File differentF = newFileFromExistingFile(f)
end
end
function readLine(File f) returns String
return line where
String line = doImperativeReadLineSystemCall(f)
end
end
Now doImperativeReadLineSystemCall reads the next line from the file using an OS level system call which has the side effect of changing the current position in the file. But this violates referential transparency because calling it multiple times with the same argument will return different results each time as the current position in the file gets moved. This in turn makes readLine violate referential transparency because it calls doImperativeReadLineSystemCall. However, using uniqueness typing, we can construct a new version of readLine that is referentially transparent even though it's built on top of a function that's not referentially transparent:
function readLine2(unique File f) returns (unique File, String)
return (differentF, line) where
String line = doImperativeReadLineSystemCall(f)
File differentF = newFileFromExistingFile(f)
end
end
The unique declaration specifies that the type of f is unique; that is to say that f may never be referred to again by the caller of readLine2 after readLine2 returns, and this restriction is enforced by the type system. And since readLine2 does not return f itself but rather a new, different file object differentF, this means that it's impossible for readLine2 to be called with f as an argument ever again, thus preserving referential transparency while allowing for side effects to occur.
«unique» декларациясы f түрінің бірегей екенін көрсетеді; яғни, readLine2 функциясы қайтарылғаннан кейін шақырушы readLine2 функциясына f аргументі ретінде қайтадан жіберілмейді, және бұл шектеу типтік жүйемен күшіне енгізіледі. readLine2 функциясы f-ті қайтармайды, керісінше, жаңа, басқа файл объектісі differentF-ті қайтарады, бұл readLine2 функциясын f аргументімен қайта шақыру мүмкін емес екенін білдіреді, осылайша сілтемелік ашықтықты сақтай отырып, жанама әсерлерге жол береді.
function readLine(File f) returns String
return line where
String line = doImperativeReadLineSystemCall(f)
end
end
Now doImperativeReadLineSystemCall reads the next line from the file using an OS level system call which has the side effect of changing the current position in the file. But this violates referential transparency because calling it multiple times with the same argument will return different results each time as the current position in the file gets moved. This in turn makes readLine violate referential transparency because it calls doImperativeReadLineSystemCall. However, using uniqueness typing, we can construct a new version of readLine that is referentially transparent even though it's built on top of a function that's not referentially transparent:
function readLine2(unique File f) returns (unique File, String)
return (differentF, line) where
String line = doImperativeReadLineSystemCall(f)
File differentF = newFileFromExistingFile(f)
end
end
The unique declaration specifies that the type of f is unique; that is to say that f may never be referred to again by the caller of readLine2 after readLine2 returns, and this restriction is enforced by the type system. And since readLine2 does not return f itself but rather a new, different file object differentF, this means that it's impossible for readLine2 to be called with f as an argument ever again, thus preserving referential transparency while allowing for side effects to occur.
Бағдарламалау тілдері
Бірегейлік типтері Clean, Mercury, SAC және Idris сияқты функционалдық бағдарламалау тілдерінде қолданылады. Кейде олар функционалдық тілдерде монадтардың орнына I/O операцияларын жүзеге асыру үшін пайдаланылады. Scala бағдарламалау тілі үшін акторлар арасындағы хабар алмасу кезінде бірегейлікті басқаруға арналған аннотацияларды қолданатын компилятор кеңейтуі жасалды.
Сызықтық типтеумен байланысы
Бірегей тип сызықтық типке өте ұқсас, сондықтан осы терминдер көбінесе бір-бірінің орнына қолданылады, бірақ бұл ретте нақты айырмашылық бар: нақты сызықтық типтеу, сызықтық емес мәнді сызықтық формаға түрлендіруге мүмкіндік береді, әрі оған бірнеше сілтеме сақталады. Бірегейлік мәннің басқа сілтемелері жоқ екеніне кепілдік береді, ал сызықтық – мәнге жаңа сілтемелер жасалмауына кепілдік береді. Сызықтық пен бірегейлік, сызықтық емес және бірегейлік емес мүмкіндіктермен салыстырғанда ерекше көзге түседі, бірақ оларды бір типтік жүйеде біріктіруге де болады.