2016-12-19 6 views
0

Je suis très nouveau à Scala. Je fonctionScala Générique Liste adition

def listSum[T](xs :List[T])(implicit abc : Numeric[T]): T = { 
    xs.sum 
    } 

    val IntList: List[Int] = List (1, 2, 3, 4) 
    val DList: List[Double] = List (1.0, 2.0, 3, 4) 

l'exemple de code ci-dessus fonctionne très bien, mais quand je change la fonction ci-dessous, il cesse de fonctionner avec l'erreur

n'a pas pu trouver la valeur implicite pour le paramètre abc: Numeric[AnyVal]

Depuis AnyVal est le type de base que je peux faire l'addition, je ne peux pas?

où tous les implicits sont-ils définis?

def listSum(xs :List[AnyVal])(implicit abc : Numeric[AnyVal]) = { 
    xs.sum 
    } 

val AList: List[AnyVal] = List (1, 2, 3, 4) 

Aussi, cela ne fonctionne pas, je pense pour la même raison.

def listSum[T](xs :List[T])(implicit abc : Numeric[T]): T = { 
    xs.sum 
    } 

    val BList : List[Boolean] = List(true, false) 
    println(listSum(BList)) 
+0

Vous ne pouvez pas additionner "anyval", car il n'est pas défini comment le faire. Vous pouvez cependant additionner des choses "numériques". Exemple 'def listSum [T: numérique] (xs: liste [T]): T = xs.sum' – Tyth

Répondre

2

Toutes les définitions implicites numérique [T] sont définis dans scala/math/Numeric.scala

(en supposant scala 2.10.4)

Il n'y a pas de définition implicite Numeric[AnyVal], donc c'est pourquoi vous obtenez l'erreur pour votre premier exemple (cela est logique, car on ne peut pas définir d'opérations numériques sans connaître le type sous-jacent)

Il n'y a pas non plus de définition implicite pour Numeric[Boolean], ce qui explique pourquoi vous obtenez l'erreur pour votre deuxième exemple (cela est également logique, car on ne peut pas définir l'opération plus, minus, times, negate, etc. sur Booleans sans supposer quoi que ce soit sur le domaine spécifique du projet).

Vous pouvez définir vous-même un Numeric[Boolean] implicite si cela a un sens pour votre projet, mais il serait préférable d'éviter d'utiliser le type numérique [T] implicite pour le type booléen.

3

Il y a plusieurs hypothèses incorrent dans votre question:

  1. AnyVal est le supertype de tous les types primitifs et value classes. Avec AnyRef c'est l'une des deux branches de type, enracinée dans le type Any, qui est le vrai supertype de tous. Ce qui signifie que l'existence de Numeric[Int] n'implique pas l'existence de Numeric[AnyVal], ce qui est très logique, si vous pensez une seconde. Les nombres entiers sont des sous-domaines des nombres réels, mais savoir comment multiplier les entiers ne signifie pas que vous savez comment multiplier les réels.
  2. Subtyping polymorphismis not directly related à restricted parametric polymorphism. La première est la plupart du temps exécutée tandis que la seconde est généralement pour la compilation. Ils interagissent de manière très spécifique dans Scala.
  3. Il n'existe pas d'endroit unique où des valeurs implicites sont définies. There are multiple places pour chaque type spécifique et place dans le code.