Поліморфізм вищого рангу надзвичайно корисний. У 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) => {}