Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala中的泛型点加法_Scala_Implicit Conversion - Fatal编程技术网

Scala中的泛型点加法

Scala中的泛型点加法,scala,implicit-conversion,Scala,Implicit Conversion,我试图用加法和scala乘法成员来填充Tuple(2)类,这样我就可以更容易地将它们用作几何二维点。这就是我得到的: implicit class Point[+T: Numeric](val t: (T, T)) { import Numeric.Implicits._ def _1 = t._1 def _2 = t._2 def +[V >: T](p: Point[V])(implicit ev: Numeric[V]) : (V,V) = (ev.pl

我试图用加法和scala乘法成员来填充Tuple(2)类,这样我就可以更容易地将它们用作几何二维点。这就是我得到的:

implicit class Point[+T: Numeric](val t: (T, T)) {
  import Numeric.Implicits._
  def _1 = t._1
  def _2 = t._2

  def +[V >: T](p: Point[V])(implicit ev: Numeric[V]) : (V,V) = 
    (ev.plus(t._1, p._1), ev.plus(t._2, p._2))
}

println((2, 3) + Point(5.0, 6.0))
这不起作用(找不到
ev
),可能是因为严格来说
Float
不是
Int
的超类型-但实际上似乎没有弱一致性约束运算符,完全忽略它意味着我不能再使用
ev.plus
,因为它需要两个相同类型的值
V
,而不是
t
V
中的一个


我怎样才能正确地实现这段代码?

你完全正确。问题是,
Numeric[T]
不允许根据签名将类型(
V
T
)混合在一起:
def plus(x:T,y:T):T

您可以使用/模拟此库: . 它做了很多隐含的体操,让混合类型的工作

它正是您所需要的:

EasyImplicits允许您对混合数字类型(例如T+U+Int)进行操作

或者选择使用底层的
Double
类型而不是
T
/
V
-我知道这并不总是很好(精度损失等)


您的代码仍然可以使用不混合类型的点,这并不是很糟糕,否则,
Double
看起来并不可怕,因为自动转换无论如何都会发生。

我相信,由于构造函数参数是一个元组,它会使本应简单的数字加宽变得复杂。这包括许多(大多数?)转换

implicit class Point[T: Numeric](a: (T, T)) {
  import Numeric.Implicits._
  val _1 = a._1
  val _2 = a._2

  def +(x: T, y: T) = add(_1, _2, x, y)

  def +[U: Numeric](x:U, y:U)(implicit ev: T => U) =
    add[U](ev(_1), ev(_2), x, y)

  def +[U: Numeric](b: Point[U])(implicit ev: T => U) =
    add[U](ev(_1), ev(_2), b._1, b._2)

  private def add[N: Numeric](a:N, b:N, c:N, d:N) = (a+c, b+d)
}
用法:

(1, 4) + (2.2, 4.4)         //res0: (Double, Double) = (3.2,8.4)
(2.1, 3.1) + (9, 2)         //res1: (Double, Double) = (11.1,5.1)
(1, 4) + Point((5.2, 6.2))  //res2: (Double, Double) = (6.2,10.2)
Point((2, 3)) + (4L, 5L)    //res3: (Long, Long) = (6,8)
Point((1.5, 2.9)) + (1, 1)  //res4: (Double, Double) = (2.5,3.9)
但是它不会扩展作为参数传递给
+()
方法的现有
点的元素

(3.3, 4.5) + Point((1, 3))  //Error:No implicit view available from Double => Int.