Змі́нна ти́пу або ти́пова змі́нна в мовах програмування та теорії типів — змінна, яка може набувати значень із множини типів даних.
Ти́пову змінну використовують у визначенні алгебричного типу даних подібно до того, як використовують параметр у визначенні функції, але застосовується для передання типу даних без передавання самих даних. Як ідентифікатори ти́пових змінних у теорії типів традиційно використовують літери грецького алфавіту (хоча багато мов програмування використовують латиницю і допускають довші назви).
Приклад
У такому визначенні «список» мовою Standard ML, ідентифікатор 'a
(читається «альфа») є змінною типу:
datatype 'a list = nil | :: of 'a * 'a list
При використанні цього у типову змінну підставляється конкретний тип, так що в програмі можна сформувати багато мономорфних типів: string list
, int list
, int list list
і т. д. За такої підстановки замість кожної згадки змінної типу підставляється один і той самий тип. Отримана інформація про типи використовується для верифікації та оптимізації програми, після чого зазвичай стирається, тому один і той самий цільовий код обробляє об'єкти спочатку різних типів (але існують і винятки з цього правила, зокрема, в ). Якщо поліморфний тип параметризовано декількома змінними типу, то типи можуть бути як різними, так і ідентичними, але правило підстановки дотримується. Наприклад, якщо такий тип:
datatype ('a,'b) t = Single of 'a | Double of 'a * 'a | Pair of 'a * 'b
інстанцувати так:
type t_ir = (int, real) t
то Single(4)
, Double(4,5)
і Pair(4,5.0)
будуть допустимими значеннями типу t_ir
, а спроба побудувати значення Single(5.0)
призведе до , оскільки параметр 'a
отримав значення «int
».
Зв'язування та квантифікація
Область дії будь-якої ти́пової змінної прив'язується до певного контексту. У наступному прикладі ідентифікатор 'a
використовується в двох сигнатурах незалежно, тобто не означає вимоги рівності типів, що фактично підставляються між визначеннями:
val foo: 'a -> 'a val bar: 'a -> 'a
Це стає наочним за використання явного зв'язування (explicit scoping або explicit bounding) ти́пової змінної:
val foo: ['a] 'a -> 'a val bar: ['a] 'a -> 'a
Зв'язування обмежує область дії даної змінної типу.
У класичних діалектах ML явне зв'язування ти́пових змінних є необов'язковою можливістю і більшість реалізацій його не підтримує через непотрібність — зв'язування в них здійснюється неявно при виводі типів, що стає можливим за рахунок обмежень ранніх версій системи Гіндлі — Мілнера. У повній системі F це оголошення записується як . Такий запис називають [en]. Велика в цьому записі означає функцію шару[] типів (type-level function), параметром якої є змінна типу. Після підстановки в цю змінну конкретного типу, ця функція повертає мономорфну функцію шару значень (value-level function). Пренексом називають винесене як префікс до сигнатури типу явне зв'язування змінної типу. Ранні версії системи Гіндлі — Мілнера дозволяють лише пренексну форму, тобто вимагають, щоб інстанцування ти́пової змінної певним значенням здійснювалось до звернення до функції. Це обмеження називають — воно не тільки суттєво спрощує механізм , але й уможливлює вивід усіх або майже всіх (залежно від діалекту) типів у програмі.
Найпростіше зв'язування ти́пових змінних називають їх квантифікацією. Виділяють два випадки:
- дія змінної типу поширюється на визначення типу:
['a, 'b] 'a -> 'b -> 'a
, математично такий тип записують через квантор загальності — — тому таку змінну типу називають «універсально квантифікованою», а весь тип — «універсально поліморфним»; - дія змінної типу поширюється тільки на частину визначення типу:
['a] 'a -> (['b] 'b -> 'a)
, математично такий тип записують через квантор існування тому таку змінну називають «екзистенційно квантифікованою», а весь тип — «екзистенційним».
Далеко не завжди «перетворення» універсально поліморфного типу на екзистенційний дає застосовний практично тип чи помітні відмінності від універсального поліморфізму, але в певних випадках використання екзистенційних типів піднімає на першокласний рівень, тобто, дозволяє передавати поліморфні функції без зв'язування як параметри іншим функціям (див. ). Класичним прикладом є реалізація гетерогенного списку (див. вікіпідручник). у цьому разі стає обов'язковим, оскільки вивід типів для поліморфізму вище від рангу 2 алгоритмічно нерозв'язний.
На практиці універсально поліморфні типи дають , а екзистенційні — абстрактність типу даних.
У мові Haskell розрізняють декілька режимів (доступних у вигляді розширень мови): режим Rank2Types дозволяє лише деякі форми екзистенційних типів, що відкривають поліморфізм не вище 2-го рангу, для якого вивід типів ще розв'язний; режим RankNTypes дозволяє переміщати квантор загальності (forall a
) всередину функційних типів, що входять до складу складніших сигнатур, режим ImpredicativeTypes дозволяє довільні екзистенційні типи.
OCaml реалізує підтримку екзистенційної квантифікації за допомогою рішення, названого «локально-абстрактними типами» (locally abstract types).
У специфікації Standard ML для деяких вбудованих операцій визначено особливу квантифікацію. Її синтаксис не регламентовано, він різниться в реалізаціях мови (найчастіше просто приховується). Наприклад, сигнатура вбудованої операції додавання може спрощено виглядати приблизно так:
val + : [int, word, real] 'a * 'a -> 'a
Ця семантика реалізує примітивну форму ad-hoc-поліморфізму — об'єднання кількох фізично різних операцій додавання під єдиним ідентифікатором «+
». Розробники OCaml відмовилися від такого рішення, повністю прибравши ad-hoc-поліморфізм із мови (у пізніших версіях з'явилися узагальнені алгебричні типи даних).
Наприкінці 1980-х з'явилося розширення Гіндлі — Мілнера, що надає можливість обмежувати, за необхідності, діапазон значень для будь-якої ти́пової змінної в нововизначених типах — класи типів. Клас типів суворіше обмежує допустимі контексти типізації, дозволяючи інстанцування ти́пової змінної лише типами, що належать явно зазначеному класу.
Вперше це розширення реалізовано в основі мови Haskell, наприклад, операція порівняння на рівність має в ньому таку сигнатуру:
(==) :: (Eq a) => a -> a -> Bool
Проєкт мови наступного покоління — successor ML — відмовляється від необхідності виводу типів, спираючись на (зокрема, явне зв'язування змінних типу), що забезпечує безпосередню підтримку повної системи F з та низкою розширень, у тому числі [en] та екзистенційних типів.
Спеціальні змінні типу
Основним класом змінних типу, що використовується у всіх мовах сімейства ML, є аплікативні змінні типу, що можуть набувати значень із множини всіх допустимих у конкретній мові типів. У класичних діалектах їх синтаксично позначають як «'a
» (цифробуквений ідентифікатор, що завжди починається з одного апострофа); в Haskell як «a
» (цифробуквений ідентифікатор, який завжди починається з малої букви).
Крім цього, з розвитком ML виділялися спеціальні підкласи змінних типу.
Змінні типу, який допускає перевірку на рівність (або змінні порівнюваного типу, equality type variables), можуть набувати значень із множини всіх (англ. equality types). Їх використання дозволяє застосування операції порівняння на рівність об'єктів поліморфних типів. Позначаються як «''a
» (цифробуквений ідентифікатор, який завжди починається з двох апострофів). Цікаво, що однією з початкових цілей, заради яких розроблено класи типів, було саме узагальнення таких типових змінних зі Standard ML. Вони неодноразово зазнавали критики через суттєве (і спірно виправдане) ускладнення визначення мови та реалізації компіляторів (половина сторінок Визначення містять ту чи іншу поправку). Складні абстрактні типи даних у принципі не доцільно перевіряти на рівність, оскільки такі перевірки можуть вимагати значних витрат часу. Тому з пізніших мов сімейства ML підтримка змінних типу, що допускає перевірку на рівність, виключено. У Haskell замість них використовується клас типів Eq a
.
Імперативні змінні типу (imperative type variables) забезпечували ситуативне вирішення проблеми типобезпеки, пов'язаної з наявністю побічних ефектів у мові з . Ця проблема не виникає в чистих мовах (Haskell, [en]), але для нечистих мов (Standard ML, OCaml) поліморфізм посилань становить загрозу . Імперативні змінні типу входили в Визначення SML'90, але перестали мати власний сенс після того, як було придумано «обмеження значеннями» (value restriction), що стало частиною переглянутого визначення SML'97. Синтаксичну підтримку імперативних змінних типу SML'97 збережено для зворотної сумісності з написаним раніше кодом, але сучасні реалізації трактують їх ідентично аплікативним. Позначаються '_a'
(цифробуквенний ідентифікатор, який завжди починається з апострофа і символу підкреслення).
Слабкі змінні типу (weak type variables) використовувалися в компіляторі [en] як альтернатива імперативним змінним типу, надаючи істотно більші можливості (точніше, менші обмеження). Позначаються '1a'
, '2a'
і так далі (цифробуквенний ідентифікатор, що завжди починається з апострофа та цифри). Цифра, що безпосередньо йде за апострофом, показувала градацію «слабкості» змінної типу. Як і імперативні змінні типу, нині трактуються ідентично аплікативним.
Примітки
- ML2000, 1999.
- Тут для явного зв'язування (англ. explicit binding) ти́пової змінної використано поточний синтаксис, прийнятий у проєкті successor ML:
['a]
. Оскільки в Haskell цей синтаксис призначено як синтаксичний цукор над типомList
, для оголошення ти́пових змінних у ньому введено ключове словоforall
. - MacQueen - TypeChecking.
- MLton - Scoping.
- haskell_existentials.
- Cardelli, Wegner, 1985.
- haskell_rankNtypes.
- haskell_impredicative_types.
- OCaml extenstions. 7.13 Locally abstract types
- Philip Wadler, Stephen Blott. How to make ad-hoc polymorphism less ad hoc. — 1988. — 17 липня.
- Andrew W. Appel. A Critique of Standard ML. — Princeton University, revised version of CS-TR-364-92, 1992. — 17 липня.
Література
- Luca Cardelli, Peter Wegner. On Understanding Types, Data Abstraction, and Polymorphism. — , 1985. — С. 471—523. — ISSN 0360-0300.
- Dave MacQueen. SML'97 Conversion Guide. 1.1. Types and Type Checking.
Посилання
- Haskell-Wiki: Existential types.
- Haskell-Wiki: Rank-N types.
- Haskell-Wiki: Impredicative types.
- Scoping type variables in Standard ML.
- The ML2000 Working Group. Principles and a Preliminary Design for ML2000. — 1999.
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Zmi nna ti pu abo ti pova zmi nna v movah programuvannya ta teoriyi tipiv zminna yaka mozhe nabuvati znachen iz mnozhini tipiv danih Ti povu zminnu vikoristovuyut u viznachenni algebrichnogo tipu danih podibno do togo yak vikoristovuyut parametr u viznachenni funkciyi ale zastosovuyetsya dlya peredannya tipu danih bez peredavannya samih danih Yak identifikatori ti povih zminnih u teoriyi tipiv tradicijno vikoristovuyut literi greckogo alfavitu hocha bagato mov programuvannya vikoristovuyut latinicyu i dopuskayut dovshi nazvi PrikladU takomu viznachenni spisok movoyu Standard ML identifikator a chitayetsya alfa ye zminnoyu tipu datatype a list nil of a a list Pri vikoristanni cogo u tipovu zminnu pidstavlyayetsya konkretnij tip tak sho v programi mozhna sformuvati bagato monomorfnih tipiv string list int list int list list i t d Za takoyi pidstanovki zamist kozhnoyi zgadki zminnoyi tipu pidstavlyayetsya odin i toj samij tip Otrimana informaciya pro tipi vikoristovuyetsya dlya verifikaciyi ta optimizaciyi programi pislya chogo zazvichaj stirayetsya tomu odin i toj samij cilovij kod obroblyaye ob yekti spochatku riznih tipiv ale isnuyut i vinyatki z cogo pravila zokrema v Yaksho polimorfnij tip parametrizovano dekilkoma zminnimi tipu to tipi mozhut buti yak riznimi tak i identichnimi ale pravilo pidstanovki dotrimuyetsya Napriklad yaksho takij tip datatype a b t Single of a Double of a a Pair of a b instancuvati tak type t ir int real t to Single 4 Double 4 5 i Pair 4 5 0 budut dopustimimi znachennyami tipu t ir a sproba pobuduvati znachennya Single 5 0 prizvede do oskilki parametr a otrimav znachennya int Zv yazuvannya ta kvantifikaciyaOblast diyi bud yakoyi ti povoyi zminnoyi priv yazuyetsya do pevnogo kontekstu U nastupnomu prikladi identifikator a vikoristovuyetsya v dvoh signaturah nezalezhno tobto ne oznachaye vimogi rivnosti tipiv sho faktichno pidstavlyayutsya mizh viznachennyami val foo a gt a val bar a gt a Ce staye naochnim za vikoristannya yavnogo zv yazuvannya explicit scoping abo explicit bounding ti povoyi zminnoyi val foo a a gt a val bar a a gt a Zv yazuvannya obmezhuye oblast diyi danoyi zminnoyi tipu U klasichnih dialektah ML yavne zv yazuvannya ti povih zminnih ye neobov yazkovoyu mozhlivistyu i bilshist realizacij jogo ne pidtrimuye cherez nepotribnist zv yazuvannya v nih zdijsnyuyetsya neyavno pri vivodi tipiv sho staye mozhlivim za rahunok obmezhen rannih versij sistemi Gindli Milnera U povnij sistemi F ce ogoloshennya zapisuyetsya yak L a l x a x displaystyle Lambda alpha lambda x alpha x Takij zapis nazivayut en Velika L displaystyle Lambda v comu zapisi oznachaye funkciyu sharu utochniti tipiv type level function parametrom yakoyi ye zminna tipu Pislya pidstanovki v cyu zminnu konkretnogo tipu cya funkciya povertaye monomorfnu funkciyu sharu znachen value level function Preneksom nazivayut vinesene yak prefiks do signaturi tipu yavne zv yazuvannya zminnoyi tipu Ranni versiyi sistemi Gindli Milnera dozvolyayut lishe preneksnu formu tobto vimagayut shob instancuvannya ti povoyi zminnoyi pevnim znachennyam zdijsnyuvalos do zvernennya do funkciyi Ce obmezhennya nazivayut vono ne tilki suttyevo sproshuye mehanizm ale j umozhlivlyuye vivid usih abo majzhe vsih zalezhno vid dialektu tipiv u programi Najprostishe zv yazuvannya ti povih zminnih nazivayut yih kvantifikaciyeyu Vidilyayut dva vipadki diya zminnoyi tipu poshiryuyetsya na viznachennya tipu a b a gt b gt a matematichno takij tip zapisuyut cherez kvantor zagalnosti a b a b a displaystyle forall a forall b a rightarrow b rightarrow a tomu taku zminnu tipu nazivayut universalno kvantifikovanoyu a ves tip universalno polimorfnim diya zminnoyi tipu poshiryuyetsya tilki na chastinu viznachennya tipu a a gt b b gt a matematichno takij tip zapisuyut cherez kvantor isnuvannya a b a b a displaystyle forall a exists b a rightarrow b rightarrow a tomu taku zminnu nazivayut ekzistencijno kvantifikovanoyu a ves tip ekzistencijnim Daleko ne zavzhdi peretvorennya universalno polimorfnogo tipu na ekzistencijnij daye zastosovnij praktichno tip chi pomitni vidminnosti vid universalnogo polimorfizmu ale v pevnih vipadkah vikoristannya ekzistencijnih tipiv pidnimaye na pershoklasnij riven tobto dozvolyaye peredavati polimorfni funkciyi bez zv yazuvannya yak parametri inshim funkciyam div Klasichnim prikladom ye realizaciya geterogennogo spisku div vikipidruchnik u comu razi staye obov yazkovim oskilki vivid tipiv dlya polimorfizmu vishe vid rangu 2 algoritmichno nerozv yaznij Na praktici universalno polimorfni tipi dayut a ekzistencijni abstraktnist tipu danih U movi Haskell rozriznyayut dekilka rezhimiv dostupnih u viglyadi rozshiren movi rezhim Rank2Types dozvolyaye lishe deyaki formi ekzistencijnih tipiv sho vidkrivayut polimorfizm ne vishe 2 go rangu dlya yakogo vivid tipiv she rozv yaznij rezhim RankNTypes dozvolyaye peremishati kvantor zagalnosti forall a vseredinu funkcijnih tipiv sho vhodyat do skladu skladnishih signatur rezhim ImpredicativeTypes dozvolyaye dovilni ekzistencijni tipi OCaml realizuye pidtrimku ekzistencijnoyi kvantifikaciyi za dopomogoyu rishennya nazvanogo lokalno abstraktnimi tipami locally abstract types U specifikaciyi Standard ML dlya deyakih vbudovanih operacij viznacheno osoblivu kvantifikaciyu Yiyi sintaksis ne reglamentovano vin riznitsya v realizaciyah movi najchastishe prosto prihovuyetsya Napriklad signatura vbudovanoyi operaciyi dodavannya mozhe sprosheno viglyadati priblizno tak val int word real a a gt a Cya semantika realizuye primitivnu formu ad hoc polimorfizmu ob yednannya kilkoh fizichno riznih operacij dodavannya pid yedinim identifikatorom Rozrobniki OCaml vidmovilisya vid takogo rishennya povnistyu pribravshi ad hoc polimorfizm iz movi u piznishih versiyah z yavilisya uzagalneni algebrichni tipi danih Naprikinci 1980 h z yavilosya rozshirennya Gindli Milnera sho nadaye mozhlivist obmezhuvati za neobhidnosti diapazon znachen dlya bud yakoyi ti povoyi zminnoyi v novoviznachenih tipah klasi tipiv Klas tipiv suvorishe obmezhuye dopustimi konteksti tipizaciyi dozvolyayuchi instancuvannya ti povoyi zminnoyi lishe tipami sho nalezhat yavno zaznachenomu klasu Vpershe ce rozshirennya realizovano v osnovi movi Haskell napriklad operaciya porivnyannya na rivnist maye v nomu taku signaturu Eq a gt a gt a gt Bool Proyekt movi nastupnogo pokolinnya successor ML vidmovlyayetsya vid neobhidnosti vivodu tipiv spirayuchis na zokrema yavne zv yazuvannya zminnih tipu sho zabezpechuye bezposerednyu pidtrimku povnoyi sistemi F z ta nizkoyu rozshiren u tomu chisli en ta ekzistencijnih tipiv Specialni zminni tipuOsnovnim klasom zminnih tipu sho vikoristovuyetsya u vsih movah simejstva ML ye aplikativni zminni tipu sho mozhut nabuvati znachen iz mnozhini vsih dopustimih u konkretnij movi tipiv U klasichnih dialektah yih sintaksichno poznachayut yak a cifrobukvenij identifikator sho zavzhdi pochinayetsya z odnogo apostrofa v Haskell yak a cifrobukvenij identifikator yakij zavzhdi pochinayetsya z maloyi bukvi Krim cogo z rozvitkom ML vidilyalisya specialni pidklasi zminnih tipu Zminni tipu yakij dopuskaye perevirku na rivnist abo zminni porivnyuvanogo tipu equality type variables mozhut nabuvati znachen iz mnozhini vsih angl equality types Yih vikoristannya dozvolyaye zastosuvannya operaciyi porivnyannya na rivnist ob yektiv polimorfnih tipiv Poznachayutsya yak a cifrobukvenij identifikator yakij zavzhdi pochinayetsya z dvoh apostrofiv Cikavo sho odniyeyu z pochatkovih cilej zaradi yakih rozrobleno klasi tipiv bulo same uzagalnennya takih tipovih zminnih zi Standard ML Voni neodnorazovo zaznavali kritiki cherez suttyeve i spirno vipravdane uskladnennya viznachennya movi ta realizaciyi kompilyatoriv polovina storinok Viznachennya mistyat tu chi inshu popravku Skladni abstraktni tipi danih u principi ne docilno pereviryati na rivnist oskilki taki perevirki mozhut vimagati znachnih vitrat chasu Tomu z piznishih mov simejstva ML pidtrimka zminnih tipu sho dopuskaye perevirku na rivnist viklyucheno U Haskell zamist nih vikoristovuyetsya klas tipiv Eq a Imperativni zminni tipu imperative type variables zabezpechuvali situativne virishennya problemi tipobezpeki pov yazanoyi z nayavnistyu pobichnih efektiv u movi z Cya problema ne vinikaye v chistih movah Haskell en ale dlya nechistih mov Standard ML OCaml polimorfizm posilan stanovit zagrozu Imperativni zminni tipu vhodili v Viznachennya SML 90 ale perestali mati vlasnij sens pislya togo yak bulo pridumano obmezhennya znachennyami value restriction sho stalo chastinoyu pereglyanutogo viznachennya SML 97 Sintaksichnu pidtrimku imperativnih zminnih tipu SML 97 zberezheno dlya zvorotnoyi sumisnosti z napisanim ranishe kodom ale suchasni realizaciyi traktuyut yih identichno aplikativnim Poznachayutsya a cifrobukvennij identifikator yakij zavzhdi pochinayetsya z apostrofa i simvolu pidkreslennya Slabki zminni tipu weak type variables vikoristovuvalisya v kompilyatori en yak alternativa imperativnim zminnim tipu nadayuchi istotno bilshi mozhlivosti tochnishe menshi obmezhennya Poznachayutsya 1a 2a i tak dali cifrobukvennij identifikator sho zavzhdi pochinayetsya z apostrofa ta cifri Cifra sho bezposeredno jde za apostrofom pokazuvala gradaciyu slabkosti zminnoyi tipu Yak i imperativni zminni tipu nini traktuyutsya identichno aplikativnim PrimitkiML2000 1999 Tut dlya yavnogo zv yazuvannya angl explicit binding ti povoyi zminnoyi vikoristano potochnij sintaksis prijnyatij u proyekti successor ML a Oskilki v Haskell cej sintaksis priznacheno yak sintaksichnij cukor nad tipom a href wiki D0 A1 D0 BF D0 B8 D1 81 D0 BE D0 BA D0 B0 D0 B1 D1 81 D1 82 D1 80 D0 B0 D0 BA D1 82 D0 BD D0 B8 D0 B9 D1 82 D0 B8 D0 BF D0 B4 D0 B0 D0 BD D0 B8 D1 85 title Spisok abstraktnij tip danih List a dlya ogoloshennya ti povih zminnih u nomu vvedeno klyuchove slovo forall MacQueen TypeChecking MLton Scoping haskell existentials Cardelli Wegner 1985 haskell rankNtypes haskell impredicative types OCaml extenstions 7 13 Locally abstract types Philip Wadler Stephen Blott How to make ad hoc polymorphism less ad hoc 1988 17 lipnya Andrew W Appel A Critique of Standard ML Princeton University revised version of CS TR 364 92 1992 17 lipnya LiteraturaLuca Cardelli Peter Wegner On Understanding Types Data Abstraction and Polymorphism 1985 S 471 523 ISSN 0360 0300 Dave MacQueen SML 97 Conversion Guide 1 1 Types and Type Checking PosilannyaHaskell Wiki Existential types Haskell Wiki Rank N types Haskell Wiki Impredicative types Scoping type variables in Standard ML The ML2000 Working Group Principles and a Preliminary Design for ML2000 1999