L'instance de Numeric
n'est pas un nombre en soi, mais un objet qui propose des opérations pour effectuer l'opération arithmétique. Par exemple, un objet num
de type Numeric[Int]
peut ajouter deux entiers comme ceci: num.plus(3, 5)
Le résultat de cette opération est l'entier 7.
Pour les entiers, ce qui est très trivial. Cependant, pour tous les types numériques de base, il existe une instance implicite disponible de Numeric
. Et si vous définissez vos propres types numériques, vous pouvez en fournir un.
Par conséquent, vous devez laisser les limites pour A
ouvert et ajouter un paramètre implicite de type Numeric[A]
, avec lequel vous effectuez les calculs. Comme ceci:
def **[A](l:List[A],m:List[A])(implicit num:Numeric[A])=l.zip(m).map({t=>num.times(t._1, t._2)})
Bien sûr, num.times(a,b)
semble moins élégante que a*b
. Dans la plupart des cas, on peut vivre avec ça. Cependant, vous pouvez envelopper la valeur a
dans un objet de type Ops
qui prend en charge les opérateurs, comme ceci:
// given are: num:Numeric[A], a:A and b:A
val a_ops = num.mkNumericOps(a)
val product = a_ops * b
Puisque la méthode mkNumericOps
est déclarée implicit
, vous pouvez également importer et utiliser implicitement:
// given are: num:Numeric[A], a:A and b:A
import num._
val product = a * b
Où je mettrais la déclaration de num._ à l'importation dans le cadre de ma fonction **? – user44242
Vous devez ouvrir un bloc après le signe égal. Je n'ai pas testé cela, mais je suppose qu'il devrait ressembler à ceci: 'def ** [A] (l: liste [A], m: liste [A]) (num implicite: Numeric [A]) = {import num._; l.zip (m) .map ({t => t._1 * t._2})} '- J'essaierais de m'en passer cependant; Je ne suis pas sûr si la création de l'objet Ops de wrapper implicite affecte les performances ou si elle sera optimisée par le compilateur. – Madoc
Je pense qu'il devrait être optimisé si l'analyse d'échappement est activée, mais aucune garantie. –