Общий метод для возврата первого из двух значений
Мне нужен метод, чтобы вернуть первое из двух упорядоченных значений. Я пробовал:
def first[T <: Ordered[T]](a: T, b: T) = {
a compare b match {
case -1 | 0 => a
case 1 => b
}
}
но получить
scala> first(3,4)
<console>:9: error: inferred type arguments [Int] do not conform to method first's
type parameter bounds [T <: Ordered[T]]
first(3,4)
^
Я думаю, это потому, что Int
должен быть преобразован в RichInt
, который является Ordered[Int]
а не Ordered[RichInt]
, Что дальше?
3 ответа
Вы можете использовать тип класса Ordering
и контекст связан:
def first[T : Ordering](a: T, b: T) = {
implicitly[Ordering[T]].compare(a, b) match {
case -1 | 0 => a
case 1 => b
}
}
Обновить
Этот код может быть упрощен, если вы import scala.math.Ordered._
, Сопутствующий объектOrdered
имеет orderingToOrdered
неявное преобразование, так что все, что имеет Ordering
также будет рассматриваться как Ordered
:
import scala.math.Ordered._
def first[T : Ordering](a: T, b: T) = if (a <= b) a else b
Я думаю, что вы ищете вид, связанный
def first[T <% Ordered[T]](a: T, b: T) = {
a compare b match {
case -1 | 0 => a
case 1 => b
}
}
Затем,
scala> first(3, 2)
res3: Int = 2
За кулисами граница вида будет компилироваться в неявный параметр, который преобразует тип T
в Ordered[T]
, Ответ Даниэля Собрала имеет хорошее объяснение: каковы границы Scala и границы просмотра?
Редактировать Введенный в Scala 2.8, Ordering
может быть предпочтительным способом сравнения, но я не смог найти каких-либо четких указаний. Похоже Ordered
имеет преимущество совместимости с Java Comparable
и, как отмечали другие, существуют неявные преобразования между Ordered
а также Ordering
,
Вы можете просто использовать неявные параметры и методы упорядочения, чтобы сделать его более понятным:
def first[T](a: T, b: T)( implicit ord: Ordering[T] ) = {
import ord._
if( a <= b ) a else b
}
или если вам все равно, какой возвращается в случае равенства:
def first[T](a: T, b: T)( implicit ord: Ordering[T] ) =
ord.min(a,b)