Come faccio a convertire implicitamente tuple di vettore a Scala
Domanda
Voglio essere in grado di convertire in modo implicito tuple di numeri (Ints e doppie) in un oggetto vettoriale.
Supponendo una classe vettoriale con un metodo +
case class Vector(x: Double, y:Double){
def + (v:Vector)= new Vector(x+v.x,y+v.y)
}
Il mio obiettivo è quello di avere i seguenti lavori di codice.
val vec = (1,2)+(.5,.3) // vec == Vector(1.5,2.3)
posso farlo funzionare per Int
con il seguente
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)
Ma non riesce quando aggiungo la conversione per doppia
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
Cercando solo doppia a sugestion di 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
Che cosa devo fare per ottenere questo lavoro?
Soluzione
La sintassi di Scala è flessibile, ma non è infinitamente flessibile. In particolare, la confluenza di tuple, parametri e impliciti rende questa una zona molto pericolosa nello spazio Design Library. Come avete notato, le cose sono soggette a rotture, non funziona bene, e dare messaggi di errore criptici. Io suggerirei di evitare, se è possibile.
In particolare, vi suggerisco di fare la seguente definizione:
val V = Vector
E poi tutti i tuoi esempi funzionano come ci si aspetta, senza impliciti, magia, o messaggi d'errore criptici, e al costo di un solo personaggio per ogni vettore.
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
Non è esattamente la sintassi che si desidera, ma credetemi, è ti risparmiare dolore e mal di testa nel lungo periodo.
Altri suggerimenti
Queste conversioni implicite sono ambigue e quindi Scala non utilizzare uno di loro. Questo è il motivo per cui le ultime righe non valuteranno.
Un modo per risolvere questo problema avrebbe lasciato il int2vec
completamente, anche se questo significa che tutti gli interi sarebbero prima implicitamente convertiti in doppie.