fpg1503 fpg1503 - 1 month ago 16
Swift Question

How does Optional covariance work in Swift

How does covariance work for

Optional
s in Swift?

Say I write the following code:

var nativeOptionalView: Optional<UIView>
let button = UIButton()
nativeOptionalView = .Some(button)
var nativeOptionalButton = Optional.Some(button)

nativeOptionalView = nativeOptionalButton


It compiles and works just fine. However if I define
MyOptional
as

enum MyOptional<T> {
case Some(T)
case None
}


And write the following:

var myOptionalView: MyOptional<UIView>
let button = UIButton()
myOptionalView = .Some(button)
var myOptionalButton = MyOptional.Some(button)

myOptionalView = myOptionalButton


I get the error:


error: cannot assign value of type '
MyOptional<UIButton>
' to type '
MyOptional<UIView>
'


I understand why this errors happens with
MyOptional
, what I don't understand is why it doesn't happen with
Optional
.

Answer

It doesn't. Swift does not support custom covariant generics for now.

The Swift type checker is per expression an not global (as in Haskell). This task is handled by the Semantic Analysis in lib/Sema. The constraint system then tries to match the types and special cases of covariance are then handled for collections, and optionals.

This was a language design decision. You should be able to do everything you need with the built-in collection types and optionals. If you aren't you should probably open a radar.

Comments