Dies scheint eine klassische Frage für Entwickler zu sein, die mit Scala-Typ-Level-Programmierung arbeiten, aber ich konnte keine Lösung finden (oder weiß nicht, wie ich danach suchen soll) oder Muster dafür. Angenommen, ich habe eine Klasse wie folgt:Verwenden Sie den formlosen Mapper, ohne den Ergebnistyp angeben zu müssen
abstract class TypedTest[Args <: HList](implicit val optMapper: Mapped[Args, Option]) {
type OptArgs = optMapper.Out
def options: OptArgs // to be implemented by subclasses
}
ich Benutzer dieser Klasse will sie instanziiert mit einem HList
Typ-Parametern (Args
) und der Klasse eine Methode liefert eine HList
Instanz enthält eine Instanz von jedem angegebenen Typ abrufen in einem Option
(OptArgs
). Ich verwende formlose Klasse Mapped dafür. Beachten Sie, dass I nicht eine Instanz von Args
zur Instanziierungszeit bereitstellen muss.
Dieser Code funktioniert nicht, da der Compiler nicht den konkreten Typ von OptArgs
ableitet und sogar eine offensichtlich korrekte Implementierung wie def options = HNil
einen Kompilierungsfehler ergibt. Der gleiche Code des Aux-Muster mit:
abstract class TypedTest[Args <: HList, OptArgs <: HList](implicit val optMapper: Mapped.Aux[Args, Option, OptArgs]) {
def options: OptArgs
}
Dies zwingt mich beid Listen zum Zeitpunkt der Instanzierung angegeben werden, die die externe API unnötig ausführlichen machen. Gibt es einen Workaround dafür?
Ich habe nicht beabsichtigt, OptArgs zu einem abstrakten Typ, sondern eher ein Pfad abhängiger Typ - abhängig von dem Wert von 'optMapper'. Obwohl ich 'OptArgs' als Typalias definiert habe, konnte ich diese Definition weglassen und einfach' def options: optMapper.Out' schreiben. Pfadabhängige Typen können sinnvoll verwendet werden, auch wenn sie als abstrakte Typen definiert sind - das ist die Definition von "Mapper.Aux", um den pfadabhängigen Typ in einen Typparameter zu "konvertieren". Es kann jedoch sein, dass es in diesem Fall keine Lösung gibt. –