Поки що відповідь є хибною.
Потрібно розрізняти "параметричний" та "спеціальний перевантаження" поліморфізм. Параметричні засоби "поводяться однаково для всіх типів a", тоді як "ad hoc" - те, що Саймон називає поліморфним - змінює реалізацію на основі типу.
Приклади обох є reverse :: [a] -> [a]
, що є параметричним, а show :: Show a => a -> String
яке "тимчасовим" перевантаженим.
Якщо ви хочете більше абстрактної інтуїції, я думаю, що це допомагає розглянути класи дієслів на природній мові, які "працюють" для всіх об'єктів, як "володіти" або "думати про", які не обмежують об'єкт, але " відкривати "вимагає того, що ми можемо говорити, можна відкрити. Я можу "думати про двері" і "відчиняти двері", хоча немає сенсу, наприклад, "відкрити дерево". Ще більше взяти приклад "відкрити" - це "спеціальна поліморфність" як "відкрити вікно" і "відкрити скаргу-квиток із обслуговування клієнтів" - це дві дуже різні речі. Якщо це здається вимушеним - забудьте це! Це працює для мене.
Обидва вони вирішені під час компіляції, проте фактично "стерті". Модульні різні розширення GHC і Template Haskell і т.д. Типи будуть фактично стерті під час компіляції і ніколи не перевіряються на час виконання.
Параметрично поліморфні функції поводяться однаково для всіх типів, тому потрібно генерувати лише один фрагмент коду, тоді як компілятор вирішує під час компіляції, яку версію функції "класового типу" потрібно запускати у певній програмі. Тому також існує обмеження на один екземпляр на тип на тип класу та відповідну обробку "нового типу".
Реалізація детально описана в підручнику SPJs та Wadler та Blotts на типових класах .
a -> String
. Ви, швидше за все, матимете обмеження типу, наприкладShow a => a -> String
.