Pregunta

Quiero ser capaz de convertir implícitamente tuplas de números (Ints y dobles) en un objeto vectorial.

Asumiendo una clase de vector con un método +

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

Mi objetivo es tener el siguiente código de trabajo.

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

puedo conseguir que funcione para Int con la siguiente

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)

Sin embargo, se produce un error cuando se añada la conversión de doble

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

difíciles que se doble por sugerencia 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 

¿Qué necesito hacer para conseguir que esto funcione?

¿Fue útil?

Solución

La sintaxis de Scala es flexible, pero no es infinitamente flexible. En particular, la confluencia de tuplas, parámetros y implícitos hace esta una zona muy peligrosa en el espacio de diseño biblioteca. Como se ha notado, las cosas son propensos a romperse, no funciona bien, y dar mensajes de error crípticos. Yo sugeriría a evitar que si se puede.

En particular, le sugiero que haga la siguiente definición:

val V = Vector

Y entonces todos sus ejemplos funcionan como era de esperar, sin ningún implícitos, la magia, o mensajes de error crípticos, y al precio de un solo carácter por Vector.

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

No es exactamente la sintaxis que desee, pero confía en mí, que le ahorrará dolor y dolores de cabeza en el largo plazo.

Otros consejos

Estas conversiones implícitas son ambiguos y por lo tanto Scala no van a usar cualquiera de ellos. Esta es la razón por la que las últimas líneas no van a evaluar.

Una forma de solucionar esto dejaría al int2vec por completo, aunque esto significa que todos los enteros serían primero implícitamente convertido en Dobles.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top