2016-12-29 1 views
0

Pendant longtemps, j'ai essayé d'éviter les classes implicites mais récemment je suis tombé dedans. Pour l'instant je ne peux pas comprendre pourquoi le type de retour de ma fonction aFunc2 ne peut pas être converti en sa forme implicite comme il le fait pour le paramètre dans aFunc1.Comment utiliser une classe implicite en tant que type de résultat de fonction

object SO extends App { 
    implicit class Experiment[K, V](tpl: (K, V))(implicit o: Ordering[K], f: Fractional[V]) { 
    def foo(): String = "Bar" 
    } 

    // Works 
    println((12, 23.1).foo()) 

    // Works 
    def aFunc1[K, V](e: Experiment[K, V]): String = e.toString 
    println(aFunc1((12, 23.1))) 

    // does not - why ? 
    def aFunc2[K, V](e: Experiment[K, V]): Experiment[K, V] = (12, 23.1) 

} 

EDIT 1: En fait cela a à voir avec les types, alors laissez-moi étends l'exemple un peu:

object SO extends App { 
    implicit class Experiment[K, V](tpl: (K, V))(implicit o: Ordering[K], f: Fractional[V]) { 
    def foo(): (K, V) = (tpl._1, tpl._2) 
    } 

    // Works 
    println((12, 23.1).foo()) 

    // Works 
    def aFunc1[K, V](e: Experiment[K, V]): String = e.toString 
    println(aFunc1((12, 23.1))) 

    // still does not but K and V should actually match - i guess 
    def aFunc2[K, V](e: Experiment[K, V]): Experiment[K, V] = e.foo() 

} 

Erreur:

Error:(19, 66) type mismatch; 
found : (K, V) 
required: scratch.SO.Experiment[K,V] 
    def aFunc2[K, V](e: Experiment[K, V]): Experiment[K, V] = e.foo() 

Répondre

1

Il est un peu difficile de deviner le problème sans l'erreur réelle que vous obtenez. Vous devriez mettre à jour la question avec le message d'erreur. En regardant le code, je suppose que le problème n'est pas la "classe implicite" mais le fait que vos types ne correspondent pas.

La ligne:

def aFunc2[K, V](e: Experiment[K, V]): Experiment[K, V] = (12, 23.1) 

attend une valeur de retour de type Experiment[K,V] étaient tous les deux K et V sont spécifiées par l'appelant de votre méthode. Ce que vous renvoyez est un tuple de type (Int, Double) donc le compilateur va se plaindre.

Si vous voulez retourner un Experiment[Int, Double] alors vous devez modifier la définition de fonction:

def aFunc2[K, V](e: Experiment[K, V]): Experiment[Int, Double] = (12, 23.1) 

MISE À JOUR: Pouvez-vous essayer d'ajouter les contraintes implicites pour K et V à la définition de aFunc2? Il devrait ressembler à ceci:

def aFunc2[K: Ordering, V: Fractional](e: Experiment[K, V]): Experiment[K, V] = e.foo() 

Vous devez vous rappeler que, pour convertir un tuple (K,V) à un Experiment[K, V] vous devez avoir deux valeurs implicites dans la portée (une commande K, et une fraction V).

+0

oui c'est vrai, c'est lié aux types, donc j'ai étendu un peu ma question. – KIC

+0

@KIC J'ai ajouté une mise à jour, pouvez-vous essayer? Je dois admettre que je vole à l'aveuglette ici car je n'ai pas de configuration de distribution de scala en ce moment. –

+0

brillant qui fonctionne - THX! – KIC