Топ питань
Часова шкала
Чат
Перспективи

Параметричний поліморфізм

З Вікіпедії, вільної енциклопедії

Remove ads
Remove ads

У мовах програмування та теорії типів параметричний поліморфізм дозволяє одному й тому ж коду отримувати "загальний" тип із використанням змінних замість конкретних типів, які можуть бути підставлені за потреби.[1]:340 Параметрично поліморфні функції та типи даних іноді називають відповідно узагальненими функціями та узагальненими типами даних. Вони є основою узагальненого програмування.

Параметричний поліморфізм може бути протиставлений ad hoc поліморфізму. Параметрично поліморфні визначення є універсальними: вони поводяться однаково незалежно від того, для якого типу вони інстанційовані.[1]:340[2]:37 На відміну від цього, визначення ad hoc поліморфізму створюються окремо для кожного типу. Таким чином, ad hoc поліморфізм зазвичай підтримує лише обмежену кількість таких окремих типів, оскільки для кожного типу потрібна окрема реалізація.

Remove ads

Основне визначення

Узагальнити
Перспектива

Можна писати функції, які не залежать від типів своїх аргументів. Наприклад, тотожна функція просто повертає свій аргумент без змін. Це природно породжує сімейство можливих типів, таких як , , тощо. Параметричний поліморфізм дозволяє задати для єдиний, найзагальніший тип, вводячи універсально квантифіковану змінну типу:

Параметрично поліморфне визначення потім може бути інстанційоване шляхом підстановки будь-якого конкретного типу замість , що утворює повне сімейство можливих типів.[3]

Тотожна функція є надзвичайним прикладом, але багато інших функцій також виграють від параметричного поліморфізму. Наприклад, функція , яка з’єднує два списки, не аналізує елементи списку, а працює лише зі структурою самого списку. Тому може мати подібну сім'ю типів, таких як , тощо, де позначає список елементів типу . Найзагальніший тип, таким чином, виглядає так:

Цей тип може бути інстанційований для будь-якого типу з сім'ї.

Параметрично поліморфні функції, такі як і , кажуть, що вони параметризовані довільним типом .[4] Обидві функції і параметризовані одним типом, але функції можуть бути параметризовані довільною кількістю типів. Наприклад, функції і , які повертають перший і другий елементи пари, відповідно, можуть мати такі типи:

У виразі тип інстанційований як , а — як у виклику . Тому тип усього виразу є .

Синтаксис, який використовується для введення параметричного поліморфізму, значно відрізняється між мовами програмування. Наприклад, у деяких мовах програмування, таких як Haskell, квантор є неявним і може бути опущеним.[5] Інші мови вимагають явно визначати типи в деяких або всіх точках виклику параметрично поліморфної функції.

Remove ads

Історія

Параметричний поліморфізм вперше був введений у мови програмування в ML у 1975 році.[6] Сьогодні він існує у Standard ML, OCaml, F#, Ada, Haskell, Mercury, Visual Prolog, Scala, Julia, Python, TypeScript, C++ та інших. Java, C#, Visual Basic .NET та Delphi також додали підтримку "дженериків" для параметричного поліморфізму. Деякі реалізації типового поліморфізму зовнішньо схожі на параметричний поліморфізм, але також включають елементи ад-хок. Наприклад, C++ підтримує спеціалізацію шаблонів.

Remove ads

Предикативність, імпредикативність і поліморфізм вищого рангу

Узагальнити
Перспектива

Поліморфізм 1-го рангу (предикативний)

У предикативній типізованій системі (також відомій як пренексний поліморфізм), змінні типів не можуть бути замінені на поліморфні типи.[1]: Предикативні теорії типів включають теорію типів Мартіна-Льофа та Nuprl. Це дуже схоже на так званий "ML-стиль" або "Let-поліморфізм" (технічно Let-поліморфізм у ML має кілька інших синтаксичних обмежень). Це обмеження робить розрізнення між поліморфними і неполіморфними типами дуже важливим; таким чином, у предикативних системах поліморфні типи іноді називають схемами типів, щоб відрізняти їх від звичайних (монополіморфних) типів, які іноді називають монотипами.

Наслідком предикативності є те, що всі типи можуть бути записані у формі, яка розміщує всі квантори на зовнішній (пренексній) позиції. Наприклад, розглянемо функцію , описану вище, яка має наступний тип:

Щоб застосувати цю функцію до пари списків, необхідно підставити конкретний тип замість змінної так, щоб отриманий тип функції відповідав типам аргументів.

В імпредикативній системі може бути будь-яким типом, включаючи тип, який сам є поліморфним; таким чином, можна застосовувати до пар списків із елементами будь-якого типу — навіть до списків поліморфних функцій, таких як сама . Поліморфізм у мові ML є предикативним.[джерело?] Це тому, що предикативність разом з іншими обмеженнями робить систему типів настільки простою, що повне виведення типів завжди можливе.

Як практичний приклад, OCaml (нащадок або діалект ML) виконує виведення типів і підтримує імпредикативний поліморфізм, але в деяких випадках, коли використовується імпредикативний поліморфізм, система виведення типів є неповною, якщо програміст не надає явні анотації типів.

Поліморфізм вищого рангу

Деякі системи типів підтримують імпредикативний конструктор функційного типу, навіть якщо інші конструктори типів залишаються предикативними. Наприклад, тип дозволений у системі, яка підтримує поліморфізм вищого рангу, навіть якщо тип може бути недоступним.[7]

Тип вважається типом рангу k (для деякого цілого числа k), якщо жоден шлях від його кореня до квантора не проходить зліва від k або більше стрілок, якщо тип зображений як дерево.[1]:359 Система типів підтримує поліморфізм рангу k, якщо вона дозволяє типи з рангом, що не перевищує k. Наприклад, система типів, яка підтримує поліморфізм рангу 2, дозволяє тип , але не . Система типів, яка допускає типи будь-якого рангу, називається "ранг-n поліморфною".

Вивід типів для поліморфізму рангу 2 є вирішуваним, але для рангів 3 і вище — ні.[8][1]:359

Імпредикативний поліморфізм

Імпредикативний поліморфізм (також відомий як поліморфізм першого класу) є найпотужнішою формою параметричного поліморфізму.[1]:340 У формальній логіці визначення називається імпредикативним, якщо воно є самореференційним; у теорії типів це стосується можливості, щоб тип знаходився в області дії квантора, який його містить. Це дозволяє підстановку будь-якої змінної типу будь-яким типом, включно з поліморфними типами. Прикладом системи, яка підтримує повну імпредикативність, є System F, що дозволяє підстановку для будь-якого типу, включно із самим собою.

У теорії типів найчастіше досліджуваними імпредикативними типізованими λ-численнями є ті, що базуються на лямбда-куб, особливо System F.

Remove ads

Обмежений параметричний поліморфізм

Докладніше: Обмежена квантифікація

У 1985 році Лука Карделлі та Пітер Вегнер визнали переваги дозволу обмежень на параметри типу.[9] Багато операцій вимагають певних знань про типи даних, але можуть працювати параметрично. Наприклад, щоб перевірити, чи міститься елемент у списку, потрібно порівняти елементи на рівність. У Standard ML параметри типу форми ’’a обмежені так, щоб операція рівності була доступною; відповідно, функція має тип ’’a × ’’a list → bool, і ’’a може бути лише типом із визначеною рівністю. У Haskell обмеження досягається за допомогою вимоги, щоб типи належали до певного типового класу; отже, та сама функція має тип у Haskell. У більшості об'єктно-орієнтованих мов програмування, які підтримують параметричний поліморфізм, параметри можуть бути обмежені підтипами певного типу (див. статті Підтиповий поліморфізм і Узагальнене програмування).

Remove ads

Примітки

Loading content...

Джерела

Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.

Remove ads