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

发布于 2024-07-16 09:11:36 字数 1075 浏览 3 评论 0原文

我希望能够将数字元组(整数和双精度)隐式转换为向量对象。

假设 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)

但当我添加 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

尝试按照 Andri 的建议仅使用 double

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 

我需要做什么才能使其工作?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

美羊羊 2024-07-23 09:11:36

Scala 的语法很灵活,但并不是无限灵活。 特别是,元组、参数和隐式的融合使得这成为库设计空间中真正危险的区域。 正如您所注意到的,事情可能会发生故障、无法正常工作,并给出神秘的错误消息。 如果可以的话我建议你避免它。

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

val V = 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

这并不完全是您想要的语法,但相信我,从长远来看,它会减轻您的痛苦和头痛。

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.

过期情话 2024-07-23 09:11:36

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

解决此问题的一种方法是完全保留 int2vec ,尽管这意味着所有整数都会首先隐式转换为双精度数。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文