2009-04-01 11 views
5

Desidero essere in grado di convertire in modo implicito Tuple di numeri (Ints e double) in un oggetto vettoriale.Come convertire implicitamente Tuple in vettore in Scala

Assumendo una classe Vector 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 fallisce quando aggiungo la conversione per il doppio

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 

Cosa devo fare per farlo funzionare?

risposta

11

La sintassi di Scala è flessibile, ma non è infinitamente flessibile. In particolare, la confluenza di tuple, parametri e impliciti rende questa area molto pericolosa nello spazio di progettazione della libreria. Come hai notato, è probabile che le cose si rompano, non funzionino bene e forniscano messaggi di errore criptici. Ti suggerirei di evitarlo se puoi.

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 solo un carattere per 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.

0

Queste conversioni implicite sono ambigue e pertanto Scala non utilizzerà nessuno dei due. Questo è il motivo per cui le ultime righe non verranno valutate.

Un modo per risolvere questo problema lascerebbe lo int2vec completamente fuori, anche se questo significa che tutti gli interi saranno convertiti implicitamente in doppio.

+0

Grazie. Sono ovviamente un idiota perché non riesco ancora a farlo funzionare. – ScalaNoob