Question

I want to be able to implicitly convert Tuples of numbers (Ints and double) into a vector object.

Assuming a Vector class with a + method

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

My goal is to have the following code work.

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

I can get it to work for Int with the following

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)

But it fails when I add the convertion for 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

Trying just double per Andri's sugestion

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 

What do I need to do to get this to work?

Was it helpful?

Solution

Scala's syntax is flexible, but it's not infinitely flexible. In particular, the confluence of tuples, parameters, and implicits makes this a really dangerous area in the library design space. As you've noticed, things are likely to break, not work well, and give cryptic error messages. I'd suggest you avoid it if you can.

In particular, I suggest you make the following definition:

val V = Vector

And then all your examples work as you'd expect, without any implicits, magic, or cryptic error messages, and at the cost of only one character per 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

It's not exactly the syntax you want, but trust me, it'll save you pain and headaches in the long-run.

OTHER TIPS

These implicit conversions are ambiguous and thus Scala won't use either of them. This is the reason why the last lines won't evaluate.

One way to fix this would leave the int2vec out completely, although this means all integers would be first implicitly converted into Doubles.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top