如何在Scala中将元组隐式转换为向量

时间:2009-04-01 20:13:41

标签: scala tuples implicit

我希望能够隐式地将数字元组(Ints和double)转换为矢量对象。

假设Vector类带有+方法

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

根据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 

我需要做些什么才能让它发挥作用?

2 个答案:

答案 0 :(得分:11)

Scala的语法很灵活,但它不是无限灵活的。特别是,元组,参数和隐含的汇合使得这在图书馆设计空间中成为一个非常危险的区域。正如您所注意到的,事情可能会破裂,不能正常工作,并提供神秘的错误消息。如果可以,我建议你避免使用它。

特别是,我建议你做出以下定义:

val V = Vector

然后你所有的例子都按照你的预期工作,没有任何暗示,魔法或神秘的错误信息,每个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

这不完全是你想要的语法,但相信我,从长远来看,它会为你省去痛苦和头痛。

答案 1 :(得分:0)

这些隐式转换是不明确的,因此Scala不会使用它们中的任何一个。这就是为什么最后一行不会评估的原因。

解决此问题的一种方法是将int2vec完全取消,尽管这意味着所有整数将首先隐式转换为双打。