Слишком много последствий! - PullRequest
2 голосов
/ 28 июля 2011

Я пишу класс 2D Vector, объявление которого выглядит следующим образом:

case class Vec2(x:Float, y:Float) extends (Float, Float)(x, y) {

    def +(v:Vec2) = Vec2(v.x+x, v.y+y)
    //Subtract, dot product, projection, etc.
    ...
    ...
}

Я бы хотел написать что-то вроде Vec2(3, 7) + (2, 9), поэтому я пишу

scala> implicit def ii2v2(i:(Int, Int)) = Vec2(i._1, i._2)
ii2v2: (i: (Int, Int))org.zhang.lib.misc.Vec2

scala> Vec2(2, 6) + (3, 1)
res25: org.zhang.lib.misc.Vec2 = (5.0,7.0)

Отлично. Но неявное не будет работать, если я попытаюсь Vec2(3, 7) + (2.6f, 9.3f), так как (Float, Float) не соответствует (Int, Int). Единственное решение, которое я нашел, это написать ЧЕТЫРЕ следствия для (Int,Int), (Int, Float), (Float, Int), and (Float, Float).

Проблема становится нелепой, когда вы пытаетесь учесть двойные числа, или когда вы пишете класс Vec3. Это можно обойти? Я мог бы просто Vec2-если все, но часть меня просто хочет добавить (Int, Int) к Vec2:)

Ответы [ 2 ]

11 голосов
/ 28 июля 2011

Сделайте следующее:

implicit def ii2v2[T: Numeric, U: Numeric](i:(T, U)) = {
  import Numeric.Implicits._
  Vec2(i._1.toFloat, i._2.toFloat)
}

При этом используются контекстные границы, чтобы сказать компилятору искать числовой [T] в области видимости, который существует для числовых типов.Импорт Numeric.Implicits._, который доступен с версии 2.9, позволяет писать toFloat.

. На 2.8 вы можете написать:

implicit def ii2v2[T, U](i:(T, U))(implicit num1: Numeric[T], num2: Numeric[U]) = {
  Vec2(num1.toFloat(i._1), num2.toFloat(i._2))
}

См. Этот другой вопрос, который похож: Написание общей средней функции в Scala

2 голосов
/ 28 июля 2011

Вы можете проверить Числовой . Также смотрите этот вопрос .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...