(Some (x), None).min 和 max 的不对称性

Asymmetry of (Some (x), None).min and max

无意中,我观察到一个不对称。

让我们列一个清单:

val li = List (Some (3), Some (2), None, Some (9)) 
li: List[Option[Int]] = List(Some(3), Some(2), None, Some(9))

scala> li.max
res54: Option[Int] = Some(9)

好的 - Some(9) 比 None 大。为什么?大会? None 是否转换为 Null 并将 Null 自动装箱为 0?

scala> li.min
res55: Option[Int] = None

看起来,好像那个印象是真的,但是让我们引入一个负数:

scala> val li = List (Some (3), Some (-2), None, Some (9)) 
li: List[Option[Int]] = List(Some(3), Some(-2), None, Some(9))

scala> li.min
res52: Option[Int] = None

scala> li.max
res53: Option[Int] = Some(9)

这很令人惊讶,至少对我来说是这样。

是的,我知道,我做错了。正确的做法是,先压平,一切都好:

scala> li.flatten.min
res57: Int = -2

scala> val li = List (Some (3), Some (2), None, Some (9)) 
li: List[Option[Int]] = List(Some(3), Some(2), None, Some(9))

scala> li.flatten.min
res56: Int = 2

但我的问题仍然悬而未决:

是否None和Some(x),缺乏其他可比性,被视为Objects,然后通过toString进行比较('N' < 'S')?

看看 source:

  trait OptionOrdering[T] extends Ordering[Option[T]] {
    def optionOrdering: Ordering[T]
    def compare(x: Option[T], y: Option[T]) = (x, y) match {
      case (None, None)       => 0
      case (None, _)          => -1
      case (_, None)          => 1
      case (Some(x), Some(y)) => optionOrdering.compare(x, y)
    }
  }
  implicit def Option[T](implicit ord: Ordering[T]): Ordering[Option[T]] =
    new OptionOrdering[T] { val optionOrdering = ord }

Some(x) 总是 被视为大于 None。没有尝试将 None 视为零或其他任何内容。因此,对于任何 A(假设所述集合包含 None),它将始终是 Option[A] 集合中的最小值。那里没有不对称,这只是惯例。我认为尝试将 None 转换为任意数字进行比较没有任何意义,因此 None 小于每个 Some(x) 是有意义的。否则,每个 Ordering[A] 都需要一个特殊的 Ordering[Option[A]] 来处理这些特殊情况,而不是上面的通用代码。