2009-04-01 16 views
5

Je veux être capable de convertir implicitement des Tuples de nombres (Ints et double) en un objet vectoriel.Comment convertir implicitement Tuples en vectoriel dans Scala

En supposant une classe Vector avec une méthode +

case class Vector(x: Double, y:Double){ 
    def + (v:Vector)= new Vector(x+v.x,y+v.y) 
} 

Mon but est d'avoir le travail de code suivant.

val vec = (1,2)+(.5,.3) // vec == Vector(1.5,2.3) 

Je peux obtenir de travailler pour Int avec les éléments suivants

implicit def int2vec(t:Tuple2[Int,Int])=new Vector(t._1,t._2) 
val vec = (1,2)+(3,4) // vec == Vector(4.0,6.0) 

Mais il échoue quand j'ajoute la convertion pour le double

implicit def int2vec(t:Tuple2[Int,Int])=new Vector(t._1,t._2) 
implicit def double2vec(t:Tuple2[Double,Double])=new Vector(t._1,t._2) 
val a = (1,2) 
val b = (.5,.3) 
val c = (1,1)+b // vec = Vector(1.5,1.3) 
val d = (1,2)+(.3,.5) // compile error: wrong number of arguments 
val e = (1,2)+((.3,.5)) // compile error: type mismatch 

Essayer simplement doubler par la Sugestion de Andri

implicit def double2vec(t:Tuple2[Double,Double])=new Vector(t._1,t._2) 
val a = (.5,.3) 
val b = (1,1)+a // type mismatch found:(Double,Double) required:String 

Que dois-je faire pour que cela fonctionne?

Répondre

11

La syntaxe de Scala est flexible, mais elle n'est pas infiniment flexible. En particulier, la confluence des tuples, des paramètres et des implicits en fait une zone vraiment dangereuse dans l'espace de conception de la bibliothèque. Comme vous l'avez remarqué, les choses risquent de se casser, de ne pas fonctionner correctement et de donner des messages d'erreur cryptiques. Je vous suggère de l'éviter si vous le pouvez.

En particulier, je vous suggère de faire la définition suivante:

val V = Vector 

Et tous vos exemples fonctionnent comme on pouvait s'y attendre, sans implicits, magie, ou les messages d'erreur énigmatiques, et au prix de un seul caractère par vecteur.

val a = V(1,2)+V(.5,.3) 
val b = V(1,2)+V(3,4) 
val c = V(1,2) 
val d = V(.5,.3) 
val e = V(1,1)+b 
val f = V(1,2)+V(.3,.5) 
val g = V(.5,.3) 
val h = V(1,1)+a 

Il est pas exactement la syntaxe que vous voulez, mais croyez-moi, ça va vous faire économiser de la douleur et des maux de tête à long terme.

0

Ces conversions implicites sont ambiguës et Scala n'utilisera donc aucune d'entre elles. C'est la raison pour laquelle les dernières lignes ne seront pas évaluées. Une manière de résoudre ce problème laisserait complètement le int2vec, bien que cela signifie que tous les entiers seraient d'abord implicitement convertis en doubles.

+0

Merci. Je suis évidemment un idiot car je n'arrive toujours pas à le faire fonctionner. – ScalaNoob