2011-12-09 4 views
3

J'utilise une bibliothèque qui me donne les éléments suivants (les relations peuvent être convertis implicitement aux nœuds):Comment faire fonctionner cette conversion implicite de Scala?

class Relation[A,B] 
class Node[A,B](r: Relation[A,B]) 
implicit def relation2node[A,B](r: Relation[A,B]) = new Node(r) 

J'extension Relation pour mon usage personnel:

class XRelation[A] extends Relation[A,Int] 

Relations/XRelations sont destinés à être sous-classé:

class User extends XRelation[Int] 

Nous pouvons maintenant définir aussi mes propres méthodes d'aide comme GET, conçu pour fonctionner avec un nœud et tout ce qui se transforme en noeud:

class Helper[A,B](n: Node[A,B]) { def GET {} } 

// note: this is the only way I know of to make the next example work. 
implicit def xx2node2helper[A,B,C[_,_]](x: C[A,B])(implicit f: C[A,B] => Node[A,B]) = new Helper(x) 

Ainsi, cet exemple fonctionne:

new Relation[Int,Int]().GET 

Et si j'ajoute une autre conversion implicite:

// don't understand why this doesn't work for the previous example 
// but works for the next example 
implicit def x2node2helper[A,B,C](x: C)(implicit f: C => Node[A,B]) = new Helper(x) 

Je peux aussi faire le travail de conversion suivante:

new XRelation[Int]().GET 

Mais cela ne fonctionne pas:

new User().GET 

Malheureusement, ce échoue avec:

error: No implicit view available from Sandbox3.User => Sandbox3.Node[A,B] 

Quelqu'un peut-il donner un sens à tout cela et expliquer comment obtenir le dernier exemple de travailler? Merci d'avance.

Mise à jour: Je sais que vous pouvez simplement introduire des conversions implicites de Relation, mais je demande à (1) comprendre comment faire cela sans avoir à introduire implicits de chaque type simple qui pourrait éventuellement convertir implicitement Node et (2) consolider ma compréhension des implicites. La résolution de la scala ne va plus loin que dans une super classe lors de la vérification si l'utilisateur correspond au modèle de type C[_,_]

Répondre

4
implicit def nodeLike2Helper[R, C <: R](r:C)(implicit f: R => Node[_,_]) = { 
    new Helper(r) 
} 

Tout comme le message d'erreur indique, User n'a pas de conversion implicite Node . Mais c'est super-super-classe Relation a. Donc, vous donnez juste les bonnes limites pour taper des paramètres.

Pour votre information, il y a un sucre de syntaxe <% pour les limites de vue, de sorte que le code ci-dessus peut être plus courte:

implicit def nodeLike2Helper[R <% Node[_,_], C <: R](r:C) = { 
    new Helper(r) 
} 
1

Vous pouvez résoudre ce problème en supprimant le motif dans le code suivant.

implicit def x2node2helper[A,B](x: Relation[A,B])(implicit f: Relation[A,B] => Node[A,B]) = new Helper(x) 

Et si le relation2node implicite dans la portée de la définition de x2node2helper alors il peut être écrit

implicit def x2node2helper[A,B](x: Relation[A,B]) = new Helper(x) 
+0

Merci, mais je demande à (1) comprendre comment faire cela sans avoir à introduire des implicits de chaque type qui pourrait éventuellement implicitement se convertir en Node, et (2) vraiment consolider ma compréhension des implicits. Clarifier ma question. – Yang

Questions connexes