【问题标题】:Scala Some redundant covarianceScala 一些冗余协方差
【发布时间】:2017-06-01 13:39:13
【问题描述】:

Scala 标准库包含Option 类型。
Option 类型本身是协变类型,这从它的声明sealed abstract class Option[+A] 中很明显。

问题是:
为什么它的构造函数Some也是协变的 final case class Some[+A](x: A) extends Option[A]?
模式匹配是否需要这种方式?
或者可能是为了提高可读性?

对我来说,这似乎是多余的,因为除了模式匹配之外,我没有任何理由直接在任何地方使用 Some,但目前我看不出它如何依赖协方差。

【问题讨论】:

  • 不是构造函数,而是协变的。这是实际的 class Some。如果它不是协变的,那么Some("foo") 就不会是Some(new Object) 的子类。
  • @Dima 我觉得这很令人困惑,因为 Some("foo")Some(new Object) 实际上不是类......但事实上,Some[String]Some[AnyRef] 的子类型是有道理的。
  • @Dima 我的意思是代数数据类型的数据构造函数。

标签: scala pattern-matching option covariance algebraic-data-types


【解决方案1】:

首先,你必须明白,正如@Dima 所说,Some[T] 不是构造函数,而是Option[T] 的子类。

一旦我们确定了这一点,使用DogAnimal 解决具有方差的问题总是更容易:

Some[Dog]Some[Animal] 吗?我想你会同意答案是肯定的。

实际上,它不会有太大变化,因为您很少使用Some[Dog],而是使用Option[Dog],但它可能会发生(例如,当您使用签名返回的案例类的unapplySome[Tuple]),那么为什么不添加方差呢?

【讨论】:

  • 能否请您提供一个更精确的示例以及 unapply 方法。为什么 unapply 应该返回 Some[Tuple] 而不是 Option[Tuple]?但是,是的,如果我们可以使用协方差以防万一我们为什么不应该这样做。我认为这可能还有其他原因。
  • 一个更好的问题可能是为什么任何东西都是协变的?我的意思是,Option 也可能是不变的。例如,在 java 中,一切都是不变的,并且可以正常工作。那么,何苦呢?答案当然是因为它有意义。如果DogAnimal 的子类,那么Some[Dog] 应该是Some[Animal] 的子类。如果不是,那就错了。
  • @Dima 我了解协方差的含义,也知道在 java 中一切都是不变的,所以你说有一些潜规则,如果没有其他数据类型,scala 中的数据类型默认是协变的为什么它们是不变的或逆变的?
  • @andrii.ilin 并不是所有的东西都应该是协变的,但如果它通过DogAnimal 的测试,它通常应该是。
  • @andrii.ilin 我没有说任何潜规则 :) 我要说的是,如果你理解 Option 协变的原因,那么你也应该理解那些Some(还有SeqFuture 等),因为所有这些原因都是一样的——从数据建模的角度来看是有道理的。
猜你喜欢
  • 2016-08-24
  • 2016-10-16
  • 2016-03-21
  • 2012-06-29
  • 1970-01-01
  • 2018-07-11
  • 2015-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多