Wie kann ich eine Funktion schreiben, die einen polymorphen Rückgabetyp hat, basierend auf dem Typargument des Typparameters?

8

Ich habe einen Code wie diesen:

%Vor%

Ich hätte gerne eine Funktion, die den Typ A für den Typparameter eines Subtyps verwenden kann.

%Vor%

Ich kann nicht herausfinden, wie dostuff in einer Weise deklariert wird, die funktioniert. Das nächste, was ich herausfinden kann, ist

%Vor%

Aber das funktioniert nicht, weil A in dieser Position nicht definiert ist. Ich kann etwas wie

machen %Vor%

Aber dann muss ich es wie dostuff[String, StringFoo](param) aufrufen, was ziemlich hässlich ist.

Der Compiler sollte alle Informationen enthalten, die er benötigt, um A across in den Rückgabetyp zu verschieben. Wie kann ich dies erreichen, entweder in einer Standardskalierung oder mit einer Bibliothek? Ich bin gerade auf Scala 2.10, wenn sich das auf die Antwort auswirkt. Ich bin offen für eine 2.11-only-Lösung, wenn es dort möglich ist, aber in 2.10

unmöglich     
Daenyth 10.04.2015, 19:46
quelle

2 Antworten

6

Wie Sie vielleicht wissen, können Sie, wenn Sie einen Parameter vom Typ Foo[A] haben, die Methode in nur A :

generisch machen %Vor%

Da dies möglicherweise nicht immer der Fall ist, können wir versuchen, einen impliziten Parameter zu verwenden, der die Beziehung zwischen A und B ausdrücken kann. Da wir einige der generischen Parameter nicht nur auf einen Methodenaufruf anwenden können (generische Parameter-Inferenz ist alles oder nichts), müssen wir diese in zwei Aufrufe aufteilen. Dies ist eine Option:

%Vor%

Sie können die Typen in der REPL überprüfen:

%Vor%

Eine weitere Option in den gleichen Zeilen, aber mit einer anonymen Klasse ist:

%Vor%

Hier habe ich apply anstelle von get verwendet, damit Sie die Methode natürlicher anwenden können. Wie in Ihrem Kommentar vorgeschlagen, habe ich hier <:< im Beweistyp verwendet. Für diejenigen, die mehr über diese Art von generalisierter Typ-Constraint erfahren möchten, lesen Sie mehr hier .

Sie könnten hier auch abstrakte Member anstelle von generischen Parametern verwenden. Wenn es mit generischen Typinferenzfällen kämpft, bietet dies oft eine elegante Lösung. Sie können mehr über abstrakte Typ-Mitglieder und ihre Beziehung zu Generika hier lesen.

>     
Ben Reich 10.04.2015, 20:07
quelle
5

Eine weitere Option ist die Verwendung von type members:

%Vor%

Beachten Sie, dass beide Lösungen hauptsächlich um die syntaktische Einschränkung in Scala arbeiten, dass Sie einen Typparameter einer Liste nicht reparieren können und der Compiler den anderen ableiten kann.

    
gzm0 10.04.2015 20:10
quelle