Ich habe mich dafür entschieden, in meiner Sprache Felix gewöhnliche Überladungs- und Mehrfachtypklassen anzubieten.
Ich halte (offenes) Überladen für wesentlich, besonders in einer Sprache, die viele numerische Typen hat (Felix hat alle numerischen Typen von C). Im Gegensatz zu C ++, das das Überladen missbraucht, indem Vorlagen davon abhängig gemacht werden, ist der Felix-Polymorphismus jedoch parametrisch: Sie müssen Vorlagen in C ++ überladen, da Vorlagen in C ++ schlecht gestaltet sind.
Typenklassen werden auch in Felix angeboten. Ignorieren Sie diejenigen, die C ++ kennen, aber Haskell nicht befassen, die es als überladen bezeichnen. Es ist nicht wie eine Überladung aus der Ferne, sondern wie eine Template-Spezialisierung: Sie deklarieren ein Template, das Sie nicht implementieren, und stellen dann Implementierungen für bestimmte Fälle zur Verfügung, wenn Sie sie benötigen. Die Typisierung ist parametrisch polymorph, die Implementierung erfolgt durch Ad-hoc-Instanziierung, soll jedoch nicht uneingeschränkt sein: Sie muss die beabsichtigte Semantik implementieren.
In Haskell (und C ++) können Sie die Semantik nicht angeben. In C ++ ist die Idee "Concepts" ungefähr ein Versuch, die Semantik anzunähern. In Felix können Sie die Absicht mit Axiomen, Reduktionen, Lemmas und Theoremen approximieren.
Der Haupt- und einzige Vorteil von (offenem) Überladen in einer Sprache mit guten Prinzipien wie Felix ist, dass es einfacher ist, sich Bibliotheksfunktionsnamen zu merken, sowohl für den Programmierer als auch für den Codeüberprüfer.
Der Hauptnachteil der Überladung ist der komplexe Algorithmus, der zur Implementierung erforderlich ist. Es passt auch nicht sehr gut zu Typinferenz: Obwohl die beiden nicht vollständig exklusiv sind, ist der Algorithmus, um beides zu tun, komplex genug, sodass der Programmierer die Ergebnisse wahrscheinlich nicht vorhersagen kann.
In C ++ ist dies auch ein Problem, da es einen schlampigen Matching-Algorithmus hat und auch automatische Typkonvertierungen unterstützt: In Felix habe ich dieses Problem "behoben", indem eine genaue Übereinstimmung und keine automatischen Typkonvertierungen erforderlich waren.
Ich denke, Sie haben die Wahl: Überladung oder Typinferenz. Inferenz ist nett, aber es ist auch sehr schwer, sie so zu implementieren, dass Konflikte richtig diagnostiziert werden. Ocaml teilt Ihnen beispielsweise mit, wo ein Konflikt erkannt wird, nicht jedoch, woher der erwartete Typ stammt.
Überladen ist nicht viel besser, selbst wenn Sie einen Qualitäts-Compiler haben, der versucht, Ihnen alle Kandidaten mitzuteilen. Es kann schwierig sein, zu erkennen, ob die Kandidaten polymorph sind, und noch schlimmer, wenn es sich um C ++ - Template-Hacker handelt.