Die Antwort ist bisher irreführend.
Es muss zwischen "parametrischem" und "Ad-hoc-Überladungs" -Polymorphismus unterschieden werden. Parametrisch bedeutet "verhält sich für alle Typen gleich", während "ad-hoc" - was Simon als polymorph bezeichnet - die Implementierung je nach Typ ändert.
Beispiele für beides sind reverse :: [a] -> [a]
parametrisch und show :: Show a => a -> String
"ad-hoc" überlastet.
Wenn Sie mehr von einer abstrakten Intuition wollen, denke ich, dass es hilfreich ist, die Klassen der natürlichen Sprachverben zu betrachten, die für alle Objekte "funktionieren", wie "besitzen" oder "denken", die keine Einschränkungen für das Objekt darstellen, sondern " zu öffnen "erfordert, dass das, wovon wir sprechen, geöffnet werden kann. Ich kann 'an eine Tür denken' und 'eine Tür öffnen', während es keinen Sinn macht, zB 'einen Baum zu öffnen'. Das Beispiel noch weiter zu führen "öffnen" ist "ad-hoc polymorph" als "ein Fenster öffnen" und "ein Reklamationsticket mit Kundenservice öffnen" sind zwei sehr unterschiedliche Dinge. Wenn das gezwungen zu sein scheint - vergiss es! Für mich geht das.
Beide werden jedoch zur Kompilierungszeit aufgelöst und tatsächlich "gelöscht". Modulo verschiedene GHC-Erweiterungen und Template Haskell, etc. Typen werden in der Tat zur Kompilierungszeit gelöscht und nie zur Laufzeit überprüft.
Parametrisch polymorphe Funktionen verhalten sich für alle Typen gleich, so dass nur ein Codeteil generiert werden muss, während der Compiler beim Kompilieren entscheidet, welche Version einer "typisierten" Funktion an einem bestimmten Programmpunkt ausgeführt werden muss. Aus diesem Grund gibt es auch die Einschränkung einer Instanz pro Typ pro Typklasse und die entsprechende "newtype" -Umgehung.
Die Implementierung ist in SPJs Lehrbuch und Wadler and Blotts Paper zu Typklassen beschrieben .
a -> String
. Es ist wahrscheinlicher, dass Sie eine Typeinschränkung haben, zShow a => a -> String
.