Folgendes ist in Scala möglich:
%Vor%Mit anderen Worten, Scala hat einen höheren Polymorphismus. Ich möchte Polymorphismus höherer Ordnung verwenden, um Folgendes zu tun.
%Vor% Also habe ich eine Menge von Fallklassen, Unterklassen von A
, deren Konstruktoren nicht notwendigerweise die gleiche Anzahl von Argumenten haben. Ich hätte auch gerne eine "generische" Fallklasse, etwa so:
Die Idee ist, dass ApplyA
als erstes Argument einen Konstruktor für etwas, das ein Untertyp von A
ist, und eine Liste von Argumenten verwendet. Die Methode eval
konstruiert dann, wenn möglich, eine geeignete Klasse mit dem Konstruktor (d. H. Die Liste hat die richtige Länge) und gibt sie zurück
(Dies entspricht l ( 1, 2, 3)
im obigen Beispiel List
). Was wäre der Typ des Arguments des ersten Konstruktors für ApplyA
?
Dies sollte mit Polymorphismus höherer Ordnung möglich sein, aber ich konnte nicht herausfinden, wie. Ich weiß, dass ich dies auch ohne Polymorphie höherer Ordnung tun kann, indem ich einfach Konstruktoren in Funktionen einpacke und diese Funktionen dann als erstes Argument an den Konstruktor für ApplyA
übergebe, aber ich würde gerne verstehen, wie man Polymorphie höherer Ordnung verwendet direkt.
Das Problem ist, dass das List
-Beispiel überhaupt keinen Polymorphismus höherer Ordnung beinhaltet. List.apply
benötigt nur eine variable Anzahl von Parametern:
Polymorphismus höherer Ordnung umfasst Methoden oder Typen, die Typkonstruktoren als Typparameter verwenden, z. B.
%Vor%Also nein, Sie können es nicht mit Polymorphismus höherer Ordnung machen.
@alexey_r ist ganz richtig, dass Ihr List
-Beispiel keine Polymorphie höherer Ordnung beinhaltet. Aber wenn Sie bereit sind, eine schwere Artillerie vom Typ-Typ zu verwenden , können Sie über die Komplexität Ihrer A{0,1,2}
-Konstruktoren abstrahieren etwas, das dem, wonach du fragst, ziemlich nahe kommt.
Der erste zu beachtende Punkt ist, dass Ihre generische Klasse, wie geschrieben, unmöglich implementiert werden kann,
%Vor% weil keine überprüfbare Beziehung zwischen der Konstruktivität c
und der Länge der Liste l
besteht. Wir können dieses Problem beheben, indem wir die List
durch eine HList
ersetzen und uns bei der Konvertierung von gewöhnlichen Funktionen mit beliebiger Arithmetik in Funktionen mit einem einzigen HList
Argument,
Das implizite Argument hl : FnHListerAux[C, HF]
liefert eine Konvertierung von Ihrem Konstruktor, unabhängig von seiner Artigkeit, in eine Funktion aus einem einzelnen HList-Argument. Und das implizite Argument ev : HF <:< (L => A)
weist darauf hin, dass die Länge der übergebenen HList
der Konstruktorargumente die richtige Länge hat (und FWIW eingibt, aber das ist in diesem Beispiel kaum relevant).
Tags und Links scala polymorphism