Поліморфізм вищого рангу надзвичайно корисний. У System F (основна мова набраних вами FP мов, які ви знайомі), це важливо для дозволу "набраних кодувань церкви", що насправді є системою F, що програмує. Без них система F абсолютно марна.
У системі F ми визначаємо числа як
Nat = forall c. (c -> c) -> c -> c
Доповнення має тип
plus : Nat -> Nat -> Nat
plus l r = Λ t. λ (s : t -> t). λ (z : t). l s (r s z)
який є вищим типом ( forall c.
відображається всередині цих стрілок).
Це з’являється і в інших місцях. Наприклад, якщо ви хочете вказати, що обчислення є належним стилем проходження продовження (google "кодексності haskell"), ви маєте право це як
type CPSed A = forall c. (A -> c) -> c
Навіть говорити про незаселений тип у Системі F вимагає поліморфізму вищого рангу
type Void = forall a. a
Довге і коротке цього, написання функції в системі чистого типу (System F, CoC) вимагає поліморфізму вищого рангу, якщо ми хочемо мати справу з будь-якими цікавими даними.
Зокрема, у System F ці кодування повинні бути "непередбачуваними". Це означає, що визначається forall a.
кількісно щодо абсолютно всіх типів . Це критично включає той самий тип, який ми визначаємо. В forall a. a
тому, що a
насправді могло б forall a. a
знову стояти ! У мовах, таких як ML, це не так, вони вважаються "предикативними", оскільки змінна типу кількісно визначається лише набором типів без кількісних показників (називаються монотипами). Наше визначення plus
необхідного impredicativity, а тому , що ми створення екземпляра c
в l : Nat
бути Nat
!
Нарешті, я хотів би зазначити одну з останніх причин, коли ви хотіли б як непередбачуваність, так і поліморфізм вищого рангу навіть у мові з довільно рекурсивними типами (на відміну від системи F). У Haskell є монада для ефектів, яка називається "монада потоку стану". Ідея полягає в тому, що монада потоку стану дозволяє мутувати речі, але вимагає уникати цього, щоб ваш результат не залежав від нічого змінного. Це означає, що обчислення ST помітно чисті. Для виконання цієї вимоги ми використовуємо поліморфізм вищого рангу
runST :: forall a. (forall s. ST s a) -> a
Тут, гарантуючи, що a
це пов'язано за межами сфери, де ми вводимо s
, ми знаємо, що це a
означає добре сформований тип, на який не покладаються s
. Ми використовуємо s
для парамеритизації всіх змінних речей у цій конкретній нитці стану, щоб ми знали, що a
це незалежно від змінних речей, і, таким чином, ніщо не виходить із рамки цього ST
обчислення! Чудовий приклад використання типів для виключення неправильно сформованих програм.
До речі, якщо вам цікаво вивчити теорію типів, я б запропонував інвестувати в хорошу книгу чи дві. Важко вивчити цей матеріал шматочками та шматочками. Я б запропонував одну з книг Пірса або Харпера про теорію ФЛ взагалі (і деякі елементи теорії типів). Книга "Розширені теми у видах та мовах програмування" також охоплює велику кількість теорії типів. Нарешті, "Програмування в теорії типів Мартіна Лофа" - це дуже вдале виклад теорії інтенсивного типу, який Мартін Лоф окреслив.
let sdff = (g : (f : <T> (e : T) => void) => void) => {}