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?

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top