2009-04-01 13 views
5

Я хочу, чтобы иметь возможность неявно преобразовывать Tuples чисел (Ints и double) в векторный объект.Как я неявно конвертировать Tuples в вектор в Scala

Предполагая векторную класс с методом +

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

Моя цель состоит в том, чтобы иметь следующий код работать.

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

я могу заставить его работать на Int со следующим

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) 

Но это терпит неудачу, когда я добавляю Перекодировка для двойной

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 

Попытка просто дважды за предложение приемлемо Андри в

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 

Что мне нужно сделать, чтобы заставить это работать?

ответ

11

Синтаксис Scala является гибким, но он не бесконечно гибкий. В частности, слияние кортежей, параметров и имплицитов делает это действительно опасной областью в пространстве дизайна библиотеки. Как вы заметили, все может сломаться, не работать хорошо и дать критические сообщения об ошибках. Я бы посоветовал вам избежать этого, если сможешь.

В частности, я предлагаю вам сделать следующее определение:

val V = Vector 

И тогда все ваши примеры работают, как и следовало ожидать, без какого-либо implicits, магии или загадочных сообщений об ошибках, а также за счет только один символ на вектор.

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 

Это не совсем синтаксис вы хотите, но поверьте мне, это сэкономит вам боль и головные боли в долгосрочной перспективе.

0

Эти неявные преобразования неоднозначны, и поэтому Scala не будет использовать ни один из них. Именно по этой причине последние строки не будут оцениваться.

Один из способов исправить это полностью исключает int2vec, хотя это означает, что все целые числа будут сначала неявно преобразованы в парные разряды.

+0

спасибо. Я, очевидно, идиот, поскольку я все еще не могу заставить его работать. – ScalaNoob