(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]]
来处理这些特殊情况,而不是上面的通用代码。
无意中,我观察到一个不对称。
让我们列一个清单:
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]]
来处理这些特殊情况,而不是上面的通用代码。