1

Scala standard library contains Option type.
The Option type itself is covariant type, this is obvious from its declaration sealed abstract class Option[+A].

The questions are:
Why its constructor Some is also covariant final case class Some[+A](x: A) extends Option[A]?
Is this somehow needed for pattern matching?
Or maybe it's done for better readability?

For me it seems redundant as I don't see any reason to use Some directly anywhere except in pattern matching but currently I can't see how it can depend on covariance.

dbc
  • 104,963
  • 20
  • 228
  • 340
  • 1
    It's not the _constructor_, that's covariant. It's the actual _class_ `Some`. If it wasn't covariant, then `Some("foo")` would not be a subclass of `Some(new Object)`. – Dima Jun 01 '17 at 13:59
  • @Dima I find this confusing, since `Some("foo")` and `Some(new Object)` aren't actually classes... But indeed, it makes sense that `Some[String]` is a subtype of `Some[AnyRef]`. – Cyrille Corpet Jun 01 '17 at 14:17
  • @Dima I meant data constructor of algebraic data type. – andrii.ilin Jun 01 '17 at 14:31

1 Answers1

1

First, you have to understand that, as @Dima said, Some[T] is not a constructor but a subclass for Option[T].

Once we have established that, the questions with variance are always easier to solve with Dog and Animal:

Is Some[Dog] a Some[Animal]? I think you'll agree that the answer is yes.

Pragmatically, it won't change much, since you'll seldom work with Some[Dog], but rather with Option[Dog], but it may occur (say when you use an unapply of a case class whose signature returns a Some[Tuple]), so why not add the variance while we're at it?

Cyrille Corpet
  • 5,265
  • 1
  • 14
  • 31
  • Could you please provide a more precise example with unapply method. Why should unapply return Some[Tuple] instead of Option[Tuple]? But yes, if we can use covariance just in case why shouldn't we. I thought that there could be another reason for that. – andrii.ilin Jun 01 '17 at 14:33
  • 1
    A better question to ask may be why anything at all is covariant? I mean, `Option` could be invariant too. In java, for instance, everything is invariant, and it works. So, why bother? The answer, of course, is because it makes sense. If `Dog` is a subclass of `Animal`, then `Some[Dog]` should be a subclass of `Some[Animal]`. If it isn't, it's just wrong. – Dima Jun 01 '17 at 14:58
  • @Dima I understand what covariance means and also know that in java everything is invariant, so you're saying that there is some unspoken rule that data types in scala are covariant by default if there is no other reason for them to be invariant or contravariant? – andrii.ilin Jun 01 '17 at 15:43
  • @andrii.ilin Not everything should be made covariant, but if it passes the test with `Dog` and `Animal`, it most usually should be. – Cyrille Corpet Jun 01 '17 at 15:45
  • @andrii.ilin I did not say anything about any unspoken rule :) All I am saying is that, if you understand the reasons for `Option` to be covariant, then you should also understand those for `Some` (and also `Seq`, `Future` etc.), because all those reasons are the same - it just makes sense from data modeling perspective. – Dima Jun 01 '17 at 16:03