Ответ пока вводит в заблуждение.
Необходимо проводить различие между «параметрическим» и «специальным перегрузочным» полиморфизмом. Параметрический означает «ведет себя единообразно для всех типов a», тогда как «ad-hoc» - то, что Саймон называет полиморфным - меняет реализацию на основе типа.
Примерами того reverse :: [a] -> [a]
, что является параметрическим и show :: Show a => a -> String
перегруженным.
Если вам нужна более абстрактная интуиция, я думаю, что это помогает рассмотреть классы глаголов естественного языка, которые «работают» для всех объектов, например «владеть» или «думать», которые не создают никаких ограничений для объекта, но « «открыть» требует того, о чем мы говорим, можно открыть. Я могу «думать о двери» и «открывать дверь», хотя нет смысла, например, «открывать дерево». Если взять еще один пример, то «открыть» - это «специальная полиморфность», как «открыть окно» и «открыть билет-жалобу через службу поддержки» - это две совершенно разные вещи. Если это кажется вынужденным - забудь об этом! Меня устраивает.
Однако оба они разрешаются во время компиляции и фактически «стираются». Модульные различные расширения GHC и Template Haskell и т.д. Типы будут фактически стерты во время компиляции и никогда не проверяются на время выполнения.
Параметрически полиморфные функции ведут себя одинаково для всех типов, поэтому необходимо сгенерировать только один фрагмент кода, в то время как компилятор решает во время компиляции, какую версию функции с классификацией типов следует запускать в конкретной программной точке. По этой же причине существует ограничение по одному экземпляру на тип для каждого класса типов и соответствующий обходной путь «нового типа».
Реализация подробно описана в учебнике SPJ и в Wadler and Blotts о классах типов .
a -> String
. Скорее всего, у вас будет ограничение типаShow a => a -> String
.