1

Scala标准库包含Option类型。
选项类型本身是协变类型,这从它的声明sealed abstract class Option[+A]明显可见。
Scala一些冗余协方差

的问题是:
为什么它的构造Some也是协变 final case class Some[+A](x: A) extends Option[A]
这是模式匹配需要吗?
或者也许这是为了更好的可读性?

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

+1

它不是_constructor_,它是协变的。这是实际的_class_“一些”。 如果它不是协变的,那么'Some(“foo”)'不会是'Some(new Object)'的子类。 – Dima

+0

@Dima我觉得这很容易混淆,因为'Some(“foo”)'和'Some(new Object)'实际上并不是类......但的确,“Some [String]”是一个子类型'有些[AnyRef]'。 –

+0

@Dima我的意思是代数数据类型的数据构造函数。 –

回答

1

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

一旦我们已经确定,与方差问题总是容易与DogAnimal解决:

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

务实,它不会有太大变化,因为你很少有Some[Dog]工作,而是与Option[Dog],但它可能会发生(比如当你使用的情况下,类的签名返回Some[Tuple]unapply),所以为什么不加入方差,而我们呢?

+0

你能否提供一个更加精确的例子,用不适用的方法。为什么不应用返回一些[元组]而不是选项[元组]?但是,是的,如果我们可以使用协变,以防万一我们不应该。我认为可能有另一个原因。 –

+1

要问一个更好的问题可能是为什么任何事情都是协变?我的意思是,'Option'也可以不变。例如,在Java中,一切都是不变的,它的工作原理。那么,为什么要麻烦?答案当然是因为它是有道理的。如果'Dog'是'Animal'的子类,那么'Some [Dog]'应该是'Some [Animal]'的子类。如果不是,那就错了。 – Dima

+0

@Dima我明白什么协方差意味着什么,也知道在java中一切都是不变的,所以你说有一些潜规则,默认情况下,scala中的数据类型是协变的,如果没有其他原因使它们不变或逆变? –