Haskell hat eine Vorstellung von "generischen Funktionen", die eine gewisse Ähnlichkeit mit gewöhnlichem Lispeln aufweist - da ich weder Erfahrung mit Haskell noch mit gewöhnlichem Lispeln habe, könnte ich hier sehr ungefähr sein. Dies bedeutet, dass man eine generische to_string
Einrichtung definieren kann, um eine Zeichenfolgendarstellung für alle Typen zu definieren. Natürlich muss die Einrichtung in den Sonderfällen definiert werden, aber es gibt eine to_string
Funktion, deren Signatur ist α → string
.
Werden Typen in Haskell wie in OCaml gelöscht? Wenn ja, wie unterscheidet sich die Implementierung von "generischen Funktionen" in Haskell von der von "Common Lisp", bei denen Typen dynamisch sind und daher nicht gelöscht werden?
Ich verstehe, dass Implementierungsdetails compilerspezifisch sind, aber es gibt wahrscheinlich Bestimmungen, die vielen oder allen Implementierungen gemeinsam sind.
quelle
a -> String
. Es ist wahrscheinlicher, dass Sie eine Typeinschränkung haben, zShow a => a -> String
.Antworten:
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 undshow :: 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 .
quelle
forall
Erweiterung erstellt werden).Warnung: Mein Hintergrund in CS ist nicht sehr ausgeprägt, daher verwende ich möglicherweise nicht immer das richtige Vokabular und irre mich in einigen Punkten. Sowieso ist hier mein Verständnis:
Ich denke, Sie verwechseln Generika mit Polymorphismus.
Generische Typen wie
List<Foo>
werden verwendet, um Typen zu beschreiben, die andere Typen als Parameter verwenden, und ermöglichen eine umfassendere Typprüfung.Eine generische Funktion in haskell könnte sein
count:: List a -> Int
. Es akzeptiert Listen jeglichen Typs und gibt die Anzahl der Elemente zurück. Es gibt nur eine Implementierung.Normalerweise können Sie bei der Definition von List nichts über T annehmen. Sie können es nur speichern und zurückgeben.
Ihre
to_string
Funktion ist eine polymorphe Funktion, was bedeutet, dass sie sich unter verschiedenen Umständen unterschiedlich verhält. In haskell geschieht dies mit Typenklassen, die wie Adjektive für Typen funktionieren.Sie haben eine
Show
Typenklasse, die eineshow :: a -> String
Funktion definiert .Wenn ein Typ
Foo
die Typklasse implementiertShow
, muss er die Definition von bereitstellenshow
. Dieser Typ kann dann in Funktionen verwendet werden, die dasShow
Qualifikationsmerkmal (wie inShow a => a -> whatever
) erfordern . Haskell kann keine Typen löschen, da diese Funktionen die korrekte Implementierung dershow
Funktion finden müssen.quelle