Bislang fand ich es außerordentlich befremdlich, daß Caml keine Ad-hoc-Polymorphie unterstützt. Für jeden Zahlentypen einen anderen Operator für Addition verwenden zu müssen, ist beispielsweise eine Pein.

Doch kann das Fehlen von Overloading gar ein Vorteil sein? Abgesehen von der automatischen Entscheidbarkeit des Typensystems, welche von Overloading behindert wird, gibt es vielleicht etwas, das Overloading gefährlich werden läßt.

Vergleichen wir doch einmal die Funktionen in CL und Haskell zum Testen, ob ein Element in einer Liste enthalten ist. Die Signatur von CLs member lautet:

(member item list &key (test #'eql) (test-not #'eql))

Das heißt, man kann den Gleichheitstest, der normalerweise durch eql gegeben ist, explizit für jede Verwendung der Funktion angeben. Wie sieht die Funktion in Haskell aus?

elem :: forall a. (Eq a) => a -> [a] -> Bool

Hier wird die Gleichheitsrelation durch die Eq-Typklasse bestimmt. Offenbar ist elem weniger mächtig als member!

Jeder Haskellprogrammierer kennt freilich die Funktion any als Alternative, und anstelle von elem x list kann man sicherlich stets any (= x) list schreiben, wobei die Äquivalenzrelation explizit angegeben wird. Dennoch: Eigentlich ist es doch eine Elementsuche, die man macht, nicht eine Suche über ein Prädikat. Verwendung und Intention liegen hier weiter auseinander, als wenn elem eine Möglichkeit böte, die gewünschte Äquivalenzrelation in Form eines optionalen Schlüssels anzugeben. Man beachte, daß in diesem Falle das Element, nach dem man suchte, gar nicht unbedingt Eq implementieren müßte, weshalb die Signatur plötzlich nicht mehr stimmen würde. Sie würde dann in etwa so aussehen (mit einer von mir aus dem Stegreif erfundenen Notation):

elem :: forall a. (test: a -> a = (=)) -> a -> [a] -> Bool

Doch was ist das? Die Typklasse ist verschwunden.

Wenn wir optionale Argumente einführen, werden Typklassen dann überflüssig? (Vielleicht nicht: Man beachte, daß (=) nach wie vor vom Typen Eq a => a -> a wäre, d.h. überladbar; es wäre lediglich weniger interessant oder wichtig, es zu überladen.) Behindern sie gar unsere Motivation, Funktionen mächtiger zu machen, indem wir sie gebrauch von Typklassen machen lassen, anstatt sie über die relevanten Operationen zu parametrisieren?

Wäre es möglich, Typklassen eine Art pseudodynamische Bindung (womit ich etwas zu impliziten Argumenten Analoges meine) zu geben, so daß man so etwas schreiben könnte wie:

elem x list where instance Eq Integer { a == b  =  eqv a b }

Es ist vielleicht kein Zufall, daß Haskell keine optionalen Schlüsselargumente kennt -- und Caml schon.