J'essaie d'écrire une fonction générique moyenne pondérée. Je veux assouplir les exigences sur les valeurs et les poids étant du même type. à-dire, je veux soutenir des séquences de dire: (value:Float,weight:Int)
et (value:Int,weight:Float)
arguments et non seulement: (value:Int,weight:Int)
Scala: fonction générique multipliant Numérique de types différents
Pour ce faire, je dois d'abord mettre en œuvre une fonction qui prend deux valeurs numériques génériques et retourne leur produit.
def times[A: Numeric, B: Numeric](x: B, y: A): (A, B) : ??? = {...}
Écrire la signature et la réflexion sur le type de retour, m'a fait réaliser que je dois définir une sorte de hiérarchie des Numerics pour déterminer le type de retour. c'est-à-dire x:Float*y:Int=z:Float
, x:Float*y:Double=z:Double
.
Maintenant, la classe numérique définit les opérations plus
, times
, etc. uniquement pour les arguments du même type. Je pense que je aurais besoin de mettre en œuvre un type:
class NumericConverter[Numeirc[A],Numeric[B]]{
type BiggerType=???
}
pour que je puisse écrire mon temps fonction:
def times[A: Numeric, B: Numeric](x: B, y: A): (A, B) :
NumericConverter[Numeirc[A],Numeric[B]].BiggerType= {...}
et convertir le « type plus petit » au « plus gros » et nourrir à times()
.
Suis-je sur la bonne voie? Comment pourrais-je "implémenter" le BiggerType
?
clairement que je ne peux pas faire quelque chose comme:
type myType = if(...) Int else Float
comme cela est évalué de façon dynamique, il worn't travail. Je comprends que je pourrais être capable de le faire en utilisant Scalaz, etc. mais ceci est un exercice académique et je veux comprendre comment écrire une fonction qui renvoie statiquement un type basé sur les types d'arguments.
N'hésitez pas à me faire savoir s'il y a un moyen plus simple de le faire.
mise à jour:
ce que je suis venu avec elle.
abstract class NumericsConvert[A: Numeric,B: Numeric]{
def AisBiggerThanB: Boolean
def timesA=new PartialFunction[(A,B), A] {
override def isDefinedAt(x: (A, B)): Boolean = AisBiggerThanB
override def apply(x: (A, B)): A = implicitly[Numeric[A]].times(x._1, x._2.asInstanceOf[A])
}
def timesB=new PartialFunction[(A,B), B] {
override def isDefinedAt(x: (A, B)): Boolean = !AisBiggerThanB
override def apply(x: (A, B)): B = implicitly[Numeric[B]].times(x._1.asInstanceOf[B], x._2)
}
def times: PartialFunction[(A, B), Any] = timesA orElse timesB
}
def times[A: Numeric, B: Numeric](x: B, y: A)= implicitly[NumericsConvert[A,B]].times(x,y)
qui est stupide que je vais devoir créer implicits pour les deux
IntDouble extends NumericsConvert[Int,Double]
et
DoubleInt extends NumericsConvert[Double,Int]
ne pas mentionner que le type de retour times
est maintenant Any
, mais peu importe, Je reçois des erreurs pour mes fonctions de temps. J'ai pensé que je l'ajouterais au cas où cela pourrait aider à arriver à une solution. donc côté question: comment je peux passer des types liés au contexte d'une classe/fonction à l'autre comme je suis en train de faire dans les temps.
Duh! le casting est fait en place! : D – ShS
n'hésitez pas à ajouter des références à http://scala-lang.org/files/archive/spec/2.11/06-expressions.html#value-conversions dans votre réponse pour expliquer ce qui se passe derrière la scène. – ShS
Ok, donc j'ai réussi à faire marcher ma méthode, mais il y a un petit problème avec ça. voyez si vous pouvez m'aider à le résoudre: http://stackoverflow.com/questions/43382282/scala-generic-weighted-average-function – ShS