SwiftのOptionalはただのenum?

SwiftのOptional Typeについて、よく次のような説明を見かけます。

> _T?_ は _Optional\<T\>_ のシンタックスシュガーです。

実際に _Optional_ は _enum_ で、次のように定義されています。

```swift:Optionalの定義
enum Optional<T> {
    case None
    case Some(T)
}
```

これだけ見ると、まるで _Optional_ がSwiftの型システム上に実装されているように見えます。一方でSwiftを書いていると、 _Optional_ はSwiftの型システムの一部であるように感じられます。

さて、 ___enum_ とジェネリクスを使えばSwiftの型システム上に _Optional_ を実装できるのでしょうか__。 

_Optional_ と等価な _enum_ を自作することはできるか、実際に試してみましょう。

なお、これは __Swift 1.1__ 時点での話です。将来的に言語仕様や型システムが変更される可能性があります。

検証
-------------------------

次のような自作 _Optional_ を作って実験します。

```swift:(A)
enum MyOptional<T> {
	case None
	case Some(T)
}
```

### 実験1: if文

次のコードは、Optional Typeを使ったありきたりなコードです。

```swift:(B)
let stringOrNil: String? = "ABC"
if let string = stringOrNil {
	println(string)
}
```

これをシンタックスシュガーなしで書くと次のようになります。

```swift:(C)
let stringOrNil: Optional<String> = Optional.Some("ABC")
if let string = stringOrNil {
	println(string)
}
```

_MyOptional_ で書くと次の通りです。

```swift:(D)
let stringOrNil: MyOptional<String> = MyOptional.Some("ABC")
switch stringOrNil {
case .Some(let string):
	println(string)
default:
	break
}
```

本当はif文を使って次のように書ければよかったのですが、そのような構文はありません。

```swift:(E)
// ※このコードは正しいSwiftのコードではありません。
let stringOrNil: MyOptional<String> = MyOptional.Some("ABC")
if stringOrNil == MyOptional.Some(let string) {
	println(string)
}
```

しかし、 _if let ..._ が使えないからと言って、 _Optional_ と等価な型を実装できないということにはなりません。例えば、 _if let ..._ は _switch_ のシンタックスシュガーと考えることができます（実際にシンタックスシュガーになっているかは別として、そのように考えても辻褄が合います）。

そう考えれば、 __(B)__ と __(C)__ は次のコードと等価となります。これは __(D)__ とそっくりです。

```swift:(F)
let stringOrNil: Optional<String> = Optional.Some("ABC")
switch stringOrNil {
case .Some(let string):
	println(string)
default:
	break
}
```

### 実験2: Optional Chaining

Optional Chaningはいかにも _Optional_ のための特別な構文のように思えます。

```swift:(G)
let baz = foo?.bar?.baz
```

しかし、このコードは _Optional_ の _flatMap_ メソッドを使って次のように書き換えることができます（ただし、 Swift 標準では _flatMap_ がないので [swiftf のような _Extension_](https://github.com/koher/swiftf) が必要です。 _flatMap_ についての詳細は ["SwiftのOptionalを極める"]() をご覧下さい）。

```swift:(H)
let baz = foo.flatMap { $0.bar }.flatMap { $0.baz }
```

_MyOptional_ にも _flatMap_ メソッドを実装してみましょう（後で使うので併せて _map_ メソッドも実装しておきます）。

```swift:(I)
enum MyOptional<T> {
	case None
	case Some(T)
	
	func flatMap<U>(f: (T) -> MyOptional<U>) -> MyOptional<U> {
		switch self {
		case .None:
			return .None
		case .Some(let t):
			return f(t)
		}
	}
	
	func map<U>(f: (T) -> U) -> MyOptional<U> {
		switch self {
		case .None:
			return .None
		case .Some(let t):
			return .Some(f(t))
		}
	}
}
```

すると、 _MyOptional_ でもまったく同じコードが書けます。

Optional Chainingは _flatMap_ メソッドの呼び出しのシンタックスシュガーと考えれば特に問題なさそうです。

### 実験3: 代入とCovariance

次のように継承関係にある二つのクラスがあるとします。

```swift:(J)
class Animal {}
class Cat: Animal {}
```

このとき、次のコードには一見何の問題もないように思えます。

```swift:(K)
let cat: Cat? = Cat()
let animal: Animal? = cat // Animal?にCat?を代入
```

しかし、前述の通り _Animal?_ や _Cat?_ はシンタックスシュガーなので、本来は次のようなコードを意味します。

```swift:(L)
let cat: Optional<Cat> = Optional.Some(Cat())
let animal: Optional<Animal> = cat // Optional<Animal>にOptional<Cat>を代入
```

この代入が許されるには、 _Optional\<Cat\>_ が _Optional\<Animal\>_ の派生型である必要があります。つまり、 _Optional_ は（型パラメータ _T_ について） __Covariant__ でなければなりません。

実際に上記のコードを実行してみると問題なく動作します。どうやら _Optional_ はCovariantなように見えます。

では、 _MyOptional_ で同じことをするとどうなるでしょうか。

```swift:(M)
let cat: MyOptional<Cat> = MyOptional.Some(Cat())
let animal: MyOptional<Animal> = cat // コンパイルエラー！
```

なんとコンパイルエラーになってしまいました。どうやら自作のジェネリックな _enum_ は（少なくともデフォルトでは）Covariantではないようです。

しかし、SwiftにはC#やScalaなどのように、型パラメータにVarianceを制御する構文がありません。

```swift:(N)
// ※このコードは正しいSwiftのコードではありません。
enum MyOptional<out T> { // Covariantにするために型パラメータにoutをつけたい
	case None
	case Some(T)
}
```

_MyOptional_ をCovariantにする手段がないということは、やはり _Optional_ はSwiftの型システム上に実装できない特別な型なのでしょうか。

しかし、次のように考えることもできます。

Covariantに見えた代入文はシンタックスシュガーで、実は __(K)__ や __(L)__ は次のコードと等価なのではないでしょうか。

```swift:(O)
let cat: Optional<Cat> = Optional.Some(Cat())
let animal: Optional<Animal> = cat.map {$0}
```

そうであれば、 _MyOptional_ でも同じように書くことができます。

```swift:(P)
let cat: MyOptional<Cat> = MyOptional.Some(Cat())
let animal: MyOptional<Animal> = cat.map {$0}
```

これも _Optional_ が特別であることの証拠とは言えなさそうです。

### 実験4: オーバーライドとCovariance

代入以外に _Optional_ がCovariantであるか確認する方法はないでしょうか。

派生型でメソッドをオーバーライドする場合、次のように戻り値の型を狭めることができます（Covariant return type）。

```swift:(Q)
class A {
	func animal() -> Animal {
		return Animal()
	}
}

class B : A {
	override func animal() -> Cat { // 戻り値の型をAnimalからCatに狭める
		return Cat()
	}
}
```

_Cat_ は _Animal_ の派生型であり _Animal_ として振る舞えるため、このように戻り値の型をより限定しても問題は起こりません。

では、次のコードはどうでしょうか。

```swift:(R)
class A {
	func animal() -> Animal? {
		return Animal()
	}
}

class B : A {
	override func animal() -> Cat? { // 戻り値の型をAnimal?からCat?に狭める
		return Cat()
	}
}
```

一見問題がなさそうですが、 _Animal?_ や _Cat?_ はシンタックスシュガーなため、上記のコードは次のコードと等価です。

```swift:(S)
class A {
	func animal() -> Optional<Animal> {
		return Optional.Some(Animal())
	}
}

class B : A {
	override func animal() -> Optional<Cat> { // Optional<Animal>をOptional<Cat>に狭められる？
		return Optional.Some(Cat())
	}
}
```

このコードが許されるには、 _Optional\<Cat\>_ が _Optional\<Animal\>_ の派生型である、つまり _Optional_ が型パラメータ _T_ についてCovariantである必要があります。 

この方法であれば二つのメソッドの戻り値の型が直接比較されるため、代入時のようにシンタックスシュガーで回避することはできません。

上記のコードは問題なくコンパイルを通ります。どうやら ___Optional_ は本当にCovariantなようです__。

_MyOptional_ がCovariantでないことは代入の実験で確認できていますが、念のためこの方法でも検証してみましょう。

```swift:(T)
class A {
	func animal() -> MyOptional<Animal> {
		return MyOptional.Some(Animal())
	}
}

class B : A {
	override func animal() -> MyOptional<Cat> { // コンパイルエラー！
		return MyOptional.Some(Cat())
	}
}
```

やはりコンパイルエラーになってしまいました。

これで、 _Optional_ がSwiftの型システム上に実装されていると言うのは大分苦しくなってきました。しかし、好意的に考えれば次のような解釈は可能です。

Swiftの _Optional_ は確かにCovariantですが、型パラメータにVarianceを制御する構文が __まだ存在しない__ だけで、Variance自体はSwiftの型システムの一部なのかもしれません。

何か決定的な証拠はないでしょうか。

### 実験5: 派生型

次のコードを見て下さい。

```swift:(U)
class A {
	func animal() -> Animal? {
		return Animal()
	}
}

class B : A {
	override func animal() -> Animal { // 戻り値の型をAnimal?からAnimalに狭める
		return Animal()
	}
}
```

一見自然に見えますが、例によってシンタックスシュガーを剥がすと次のようになります。

```swift:(V)
class A {
	func animal() -> Optional<Animal> {
		return Optional.Some(Animal())
	}
}

class B : A {
	override func animal() -> Animal { // 戻り値の型をOptional<Animal>からAnimalに狭める？
		return Animal()
	}
}
```

これはさすがに厳しいように思います。 _Animal_ は _Optional\<Animal\>_ の派生型になりうるでしょうか。しかし、このコードはコンパイルを通ります。

念のため、 _MyOptional_ でも試してみましょう。

```swift:(W)
class A {
	func animal() -> MyOptional<Animal> {
		return MyOptional.Some(Animal())
	}
}

class B : A {
	override func animal() -> Animal { // コンパイルエラー！
		return Animal()
	}
}
```

やはりコンパイルエラーになります。 _enum_ がAssociated Valueを持っているときに、Associated Valueの型がその _enum_ の派生型になる（ _Animal_ が _MyOptional\<Animal\>_ の派生型になる）わけではないようです。

これは決定的な証拠ではないでしょうか。 __Swiftの型システムは _Optional_ を特別扱いし、 _T_ を _Optional\<T\>_ の派生型として扱っている__ ように見えます。

しかし、Varianceのときと同じように、型システム上は _Animal_ が _MyOptional\<Animal\>_ の派生型になるかを制御でき、そのための構文がまだ存在しないだけと考えることはできないでしょうか。

VarianceについてはCovariantとContravariant、Invariantを使い分ける必要があるため、デフォルトはInvariantで、Varianceの制御のための構文が欠けていると考えても筋が通ります。しかし、 _Animal_ が _MyOptional\<Animal\>_ の派生型でいけない理由はないように思います。派生型になるかならないか制御する構文が欠けていると考えるのは不自然ではないでしょうか。やはり、現時点では _Optional_ はSwiftの型システム上に実装されたものではなく、型システムの一部であると考えるのが自然だと思います。

結論
-------------------------

以上の実験より、現時点では _Optional_ はSwiftの型システム上に実装されたものではなく、型システムの一部であると考えるのが自然だと思います（個人的な考察の結果なので、おかしな点があれば指摘してもらえるとうれしいです）。