Scala: Как я могу явно сравнить два параметра?

Если у меня есть два параметра, например

val a = Option(2)
val b = Option(1)

Я могу написать

List(a,b).sorted

и он корректно сортируется, вставив неявное упорядочение. Как я могу получить ссылку на этот заказ, чтобы я мог позвонить compare(a,b) и получить результат? Мне нужен эквивалент

val comparison = a.compare(b)

за исключением случаев, когда a и b не являются экземплярами Ordered.

Ответ 1

Вы можете просто запросить прямое указание:

Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_21).
Type in expressions to have them evaluated.
Type :help for more information.

scala> implicitly[Ordering[Option[Int]]]
res0: Ordering[Option[Int]] = [email protected]

scala> res0.compare(Some(1), Some(3))
res1: Int = -1

Ответ 2

Лучший способ манипулирования параметрами - использовать выражения for.

for (a1 <- a; b1 <- b) yield a1.compare(b1)  // Some(-1)

Если хотя бы одно из чисел None, результат None.

val x: Option[Int] = None
for (a1 <- a; b1 <- x) yield a1.compare(b1)  // None

Функция сравнения может быть определена как

def compare(a: Option[Int], b: Option[Int]) = {
  for (a1 <- a; b1 <- b) yield a1.compare(b1)
}.get

Обновлено:

Если вы хотите, чтобы Nones вы могли использовать сопоставление с образцом:

def compare(a: Option[Int], b: Option[Int]) = (a, b) match {
  case (Some(a), Some(b)) => a.compare(b)
  case (None, None)       => 0
  case (None, _)          => -1  // None comes before
  case (_, None)          => 1
}

val list: List[Option[Int]] = List(List(Some(1), None, Some(4), Some(2), None))
val list2 = list.sortWith(compare(_, _) < 0)    
//  list2 = List(None, None, Some(1), Some(2), Some(4))