Ich möchte eine allgemeine gewichtete Durchschnittsfunktion implementieren, die die Anforderungen an die Werte und die Gewichte vom gleichen Typ lockert. dh ich möchte Sequenzen von sagen: (value:Float,weight:Int)
und (value:Int,weight:Float)
Argumente und nicht nur: (value:Int,weight:Int)
. [Siehe meine früheren Frage in diesem Vorfeld .]
Das habe ich zur Zeit:
%Vor%Das funktioniert perfekt, wenn ich es zum Beispiel füttere:
%Vor% Allerdings, wenn ich die Gewichte nicht von Int
auf Float
"upcast":
Scala-Compiler wird mir sagen:
error: konnte keinen impliziten Wert für den evidence-Parameter des Typs finden Numerisch [AnyVal]
val avg = gewichtete Mittel (Werte)
Gibt es eine Möglichkeit, dies zu umgehen?
Ich hatte einen Versuch, eine NumericCombine
Klasse zu schreiben, die mich mit% parametriert co_de% und A
der „verbindet“ die Typen in einen „gemeinsamen“ Typen B
(zum Beispiel der Kombination AB
und Float
gibt dir Int
):
und ich schaffte es einfach zu schreiben Float
und times
Funktionen basierend auf dieser mit dem typeclass Muster, aber seit plus
führt ein pfadabhängigen Typ NumericCombine
, „komponieren“ die Typen erweist sich mehr zu sein Schwieriger als ich erwartet hatte. Blick auf diese Frage für weitere Informationen und Hier finden Sie hier für die vollständige Implementierung von AB
.
Aktualisieren
Eine etwas befriedigende Lösung wurde als Antwort auf hier ) aber es gibt noch Raum für einige Designverbesserung berücksichtigt die in der Diskussion mit @ziggystar angesprochenen Punkte.
Ich denke, die allgemeinere Aufgabe, bei der einige Elemente vom Typ T
mit einem Skalar vom Typ S
gewogen / skaliert werden, ist der einer linearen Kombination. Hier sind die Einschränkungen für die Gewichte für einige Aufgaben:
Der allgemeinste Fall nach dieser Klassifizierung ist also die Linearkombination.
Nach Wikipedia müssen die Gewichte S
ein Feld und T
einen Vektorraum über S
.
Bearbeiten: Die wirklich allgemeinste Anforderung, die Sie für die Typen haben können, ist, dass T
ein Modul (Wiki) über den Ring S
, oder T
ist ein S
-Modul.
Sie können diese Anforderungen mit typeclasses einrichten. Es gibt auch einen Turm , der bereits Typklassen für Field
und VectorSpace
enthält. Ich habe es nie selbst benutzt, also musst du es selbst ausprobieren.
Float
/ Int
funktioniert nicht Was aus dieser Diskussion hervorgeht und was Sie bereits beobachtet haben, ist die Tatsache, dass Float
als Gewicht und Int
als Elementtyp nicht funktionieren, da die ganzen Zahlen nicht gebildet werden ein Vektorraum über den Realen. Sie müssten Int
zuerst auf Float
hochladen.
Es gibt nur zwei Hauptkandidaten für den Skalartyp, d. h. Float
und Double
.
Und hauptsächlich ist nur Int
ein Kandidat für die Werbung, also könntest du folgendes als einfache und nicht so allgemeine Lösung machen:
Zuerst ist Ihre Vorlage falsch. (Und tut mir leid, wenn der Ausdruck "Vorlage" falsch ist - ich bin ein Neuling in Scala). Ihre Funktionen erwarten Tupel, bei denen beide Elemente vom selben Typ sind ([A: Numerisch]), anstelle von Tupeln, bei denen Elemente unterschiedlicher Typen sind ([A: Numerisch, B: Numerisch]) ((Int, Float) vs (Float, Float))
Wie auch immer, die unten stehenden Kompilationen werden hoffentlich funktionieren, nachdem Sie sie mit Ihrem gewünschten Kalkül gefüllt haben.
%Vor%Tags und Links scala generics implicit-conversion implicit