2017-07-20 1 views
1

Je viens de commencer à apprendre scala. J'essayais d'écrire une fonction pour inverser une liste de n'importe quel type arbitraire.erreur de "type incompatibilité" lors de l'utilisation: + méthode sur une liste

Voici le code:

def reverse [A] (l:List[A]):List[A] = { 
    val size:Int = lenList(l) // i have implemented this func separately 
    if (l.isEmpty) List() 
    else { 
       var newList = List() 
       for (i <- 1 to size) 
       { 
        var temp = l(size - i) 
        newList = newList :+ temp //type mismatch error here 
       } 
    newList 
    } 
    }' 

Ceci est l'erreur lorsque le code ci-dessus a été compilé:

Error

Quand j'ai changé la déclaration newList-var newList = List[A]() (qui est le même type comme la liste passée en paramètre) le code compilé avec succès.

Ma question est:

  1. Pourquoi est-il une incompatibilité de type sur la ligne newList = newList :+ temp lorsque newList est de type List[Nothing] et temp est un élément de type A?

  2. Pourquoi le compilateur dit Found:List[A] lorsqu'il n'y a pas de type List[A] impliqué dans l'instruction?

  3. Quelqu'un pourrait-il me dire la raison pour laquelle cette erreur d'incompatibilité de type particulier s'est produite?

  4. Aussi, je veux savoir la raison pour laquelle le code compilé lorsque j'ai changé la déclaration?

  5. Quel effet ma déclaration a-t-elle eu sur l'instruction qui lançait initialement l'erreur?

Je crois ci-dessous un message d'erreur aurait été justifiée dans cette situation

found:List[Nothing] 
Required:List[A] 

plutôt que ce que je rencontrais:

found:List[A] 
Required:List[Nothing] 

Comme newList de type List[Nothing] a été utilisé dans la déclaration et l'élément que j'ai essayé d'ajouter était de type A alors il est compréhensible que le type requis soit List[A] .

+1

appel à 'Liste()' correspond à l'usine 'List.apply [T]', où 'T' est déduit comme' Rien comme vous ne le spécifiez pas, ni sur la déclaration 'val' en indiquant le type explicite ou sur l'appel d'usine. soit 'val newList: Liste [A] = List()' ou 'val newList = List.empty [A]' – cchantep

Répondre

2

Quand vous faites:

var newList = List() 

Le type de newList est List[Nothing]. Et si vous êtes nouveau sur Scala, Nothing est un sous-type de tous les autres types. Pratiquement, c'est inutile, quand il faut écrire des données. Nous verrons pourquoi. Lorsque vous faites newList :+ temp, vous ajoutez temp (de type A) à un List[Nothing]. Ainsi, pour le compilateur, l'inférence de type prédit que cette nouvelle liste doit être de type List[A]. (Pensez-y, si vous créez une liste de lions, d'oiseaux et de serpents, n'allez-vous pas appeler cette nouvelle liste comme une liste d'animaux?)

Donc la liste générée est de type List[A].Et puis vous essayez de l'assigner à lui-même (newList =). Lequel est à l'origine un List[Nothing]. Dans Scala, avec var, vous pouvez modifier la valeur mais pas le type. Et ici, nous essayons de changer le type de newList de List[Nothing] à List[A].

D'où l'erreur et son explication

+1

Merci pour l'explication. Maintenant j'ai compris que 'found: List [A]' renvoyait au type résultant de la valeur renvoyée par expresion 'newList: + temp' qui était une incompatibilité pour le type requis 'List [Nothing]' de newList. –

0

utilisation newList.+:(temp) à ajouter à la liste