SwiftのOptional型を極める

本投稿の個別の説明（ `Optional` とは何か、 `?.` と `map`, `flatMap` の関係、その背後にあるモナドという概念）は 2017 年現在でも通用するものですが、 Swift の `Optional` の使い方としては、僕の考えとのズレが大きくなってきました。 **[Swift の `Optional` をいつ・どのように使うべきかについてもまとめた](http://qiita.com/koher/items/8b6156c8263b9b23c43c)** ので、そちらも併せて御覧下さい。

---

_Optional_ は Swift の仕様の中でもっとも素晴らしいものの一つだと、僕は考えています。

_null参照_ （多くの言語で `nil` や `null` と呼ばれるもの）を発明したトニー・ホーアは次のように述べています[^1]。

> それは10億ドルにも相当する私の誤りだ。null参照を発明したのは1965年のことだった。（中略）これは後に数え切れない過ち、脆弱性、システムクラッシュを引き起こし、過去40年間で10億ドル相当の苦痛と損害を引き起こしたとみられる。

__その「10億ドルの誤り」からプログラマを開放してくれるのが _Optional_ です。__

しかし、実際に _Optional_ を使い始めると、コードを書きづらいパターンがいくつかあることに気付きます。本投稿では、 _Optional_ の背景にある概念について説明し、そのようなケースのエレガントな解決法を示します。

__本投稿の主なキーワード__

- `map`, `flatMap`
- _第一級関数_, _高階関数_, _高階メソッド_
- _モナド_
- _Union type_

Optionalで書きづらいケース
----------------------------------------------------


次のようなケース（先日[「力試し」として投稿](http://qiita.com/koher/items/627a90017e3d4be1dd5b)したものです）では、 _Optional binding_ （ `if let ...` ）などで書こうとするとコードが複雑になってしまいます。

> `Optional` を使って次のことをやる場合に、 __簡潔かつ安全__ に書く方法を考えて下さい。
>
> 1. `a: Int?` があるとき、 `a` の値を二乗したい。ただし、 `a` が `nil` の場合は `nil` を得たい。
> 2. `array: [Int]?` があるとき、 `array` の最初の要素を取得したい。ただし、 `array` が `nil` か、最初の要素が存在しない（ `Array` が空の）場合は `nil` を得たい。（ヒント：  `[Int]` は `first: Int?` というプロパティを持つ。 `first` は最初の要素が存在しない場合は `nil` を返す。）
> 3. `x: Double?` があるとき、 `x` の平方根を計算したい。ただし、 `x` が `nil` または負の数の場合は `nil` を得たい。なお、 `sqrt` を安全にした（負の数を渡すと `nil` を返す）関数 `safeSqrt: Double -> Double?` があるものとして考えて良い。
> 4. `a: Int?` と `b: Int?` があるとき、 `a + b` を計算したい。ただし、 `a` か `b` が `nil` の場合には `nil` を得たい。
> 5. `a: Int?` があるとき、 `a` の値を `print` で表示したい。ただし、 `a` が `nil` の場合には何も表示したくない。
>
> 1, 2, 4 では結果の型が（ `Int` ではなく） `Int?` に、 3 では `Double?` になることに注意して下さい。また、 3 の `safeSqrt` は次のように実装できます。
>
> ```swift
func safeSqrt(x: Double) -> Double? {
	return x < 0.0 ? nil : sqrt(x)
}
```


例えば、 1 の答えを _Optional binding_ を使って書くと次のようになります。

```swift
let result: Int?
if let a0 = a {
	result = a0 * a0
} else {
	result = nil
}
```

ただ値を二乗したいだけなのに複雑すぎます。もし `a` が `Int?` ではなく `Int` なら
`a * a` で済むコードが 6 行にもなってしまっています。

別の方法として、 `nil` チェックと三項演算子、 _Forced unwrapping_ （ `!` ）を組み合わせれば 1 行で次のように書くことはできます。

```swift
let result: Int? = a == nil ? nil : a! * a!
```

しかし、 `!` は安全ではないので極力使いたくないですし、短いだけで簡潔とも言いづらいです。そもそも、 `nil` チェックが必要なんて _null参照_ 時代に逆戻りでせっかくの _Optional_ が台無しです。

Optionalの考え方
----------------------------------------------------

解答の前に、まずはどのようなイメージで _Optional_ をとらえればよいか説明します。

_Optional_ を __`nil` も入れられる型__ だと考えている人は多いと思います。よくあるのは次のような理解でしょうか。

- `Foo` 型の変数には `nil` を代入できないけど、 `Foo?` にすれば `nil` も入れられる。
- `Foo?` 型の変数はそのままでは使えないので _Optional binding_ （ `if let = ...` ）や _Forced unwrapping_ （ `!` ）を使って `Foo` 型に変換してから使う。

これらは間違ってはいないですが、 _Optional_ の正確な理解とは言えません。

### Foo? は Optional\<Foo\> と等価

まず、 Swift の _Optional_ は `Optional` という一つの型です。 `Foo?` は `Optional<Foo>` を表すシンタックスシュガーで、どちらで書いても同じ意味になります。

```swift
let a: Optional<Int> = 3 // Int? と書いたのと等価
```

これは、 `[Foo]` が `Array<Foo>` と等価なのと同じです。

### Foo? が Foo のメソッドを呼べない理由

次のコードがコンパイルエラーになるのは当然ですよね？

```swift
let a: Array<Int> = [3]
let b = a * a // コンパイルエラー： Array に対して * が呼び出せるわけがない
```

`Optional` についても全く同じ理由でエラーになります。

```swift
let a: Optional<Int> = 3
let b = a * a // コンパイルエラー： Optional に対して * が呼び出せるわけがない
```

つまり、 `Foo?` を `Foo` として使えないのは `Foo?` が `nil` かもしれないからではなく、 `Foo?` （ `Optional<Foo>` ）は `Foo` とはまったく異なる型だからです。 __`String` を `Int` として使えないのと同じ話です__。

なお、 `Optional<Foo>` は `Foo` のメソッドを呼ぶことはできませんが `Optional` のメソッドを呼ぶことはできます。 `nil` は `Optional` 型の値なので[^2] `nil` に対して `Optional` のメソッドを呼び出すことも可能です。

```swift:nilに対してメソッドを呼び出す
let a: Optional<Int> = nil
a.getMirror() // Optional<Int> の持つ getMirror メソッドを呼ぶ → エラーにならない
```

`Foo?` を `nil` も入れられる型だと考えていたら、なんで `nil` に対してメソッドを呼ぶことができるのか理解しづらいと思います。 Swift の `nil` は `Optional` 型の値[^2]であって _null参照_ とはまったく別の概念です。

 ___Optional_ について混乱したときには、 `Foo?` ではなく `Optional<Foo>` だと考えてみることをオススメします__。ただそれだけのことで考えを整理しやすくなると思います。

### Optionalは箱と考える

`Foo?` を `nil` も入れられる型だと考えないのであれば、どのようなイメージでとらえると良いでしょうか。僕は、 __`Foo?` は `Foo` 型の値を入れられる箱だと考える__ とわかりやすいと思います。

箱の中身は空（ `nil` ）かもしれないし、値が入っているかもしれません。値を使うには箱から取り出さなければ（ _unwrap_ しなければ）いけません。

このイメージの違いは些細なことに感じられるかもしれませんが、箱というより正確なメタファーで与えることで、次のような複雑なケースもシンプルに理解することができます。

```swift
let a: Int?? = 3
```

_Optional_ を `nil` も入れられる型だと考えていると `Int??` を理解しづらいです。しかし、 _Optional_ を箱だと考えると、 `Int??` （ `Optional<Optional<Int>>` ）は箱が二重になっており、内側の箱の中に `Int` が入ってるとイメージできます。箱が二重になっているなら、 箱を二回開けて中身を取り出さないと中の値を使えないことがすぐにわかります。

```swift:箱を二回開けて中身を取り出す
let a: Int?? = 3
if let a0: Int? = a { // 外の箱を開けて内の箱を取り出す
	if let a1: Int = a0 { // 内の箱を開けて値を取り出す
		println(a1) // 3
	}
}
```

箱から取り出さずに中身を操作する
----------------------------------------------------

_Optional_ は _null参照_ と違って安全で素晴らしいですが、 _Optional_ を使った安全なコードを書いているとすぐに箱（ _Optional_ ）だらけになってしまいます。そして、「力試し」の 1 （下に再掲）のように箱の中身をちょっと操作したいと思っただけで、わざわざ箱から値を取り出して操作してもう一度箱に詰めるというわずらわしい作業が必要になります。

> _1._ `a: Int?` があるとき、 `a` の値を二乗したい。ただし、 `a` が `nil` の場合は `nil` を得たい。

できることなら、箱から中身を取り出さずに箱の中身だけ操作できれば簡単です。 `Optional` には、そのための道具 `map` メソッドが用意されています。

```swift:1の解答
let result: Int? = a.map { $0 * $0 } // 箱が空でなければ中身を二乗する
```

とてもシンプルですね！

しかし、上記のコードを見てもどういう構文なのかよくわからないという人も多いかと思います。これを理解するには次の各ステップを理解する必要があります。

### 第一級関数

Swift では関数を、

- 変数に代入する
- 関数やメソッドの引数として渡す
- 関数やメソッドの戻り値として返す

ことができます。このことを、「 Swift の関数は ___第一級関数___ である」と言います。

```swift:関数を変数に代入する例
func square(x: Int) -> Int { // 引数を二乗して返す関数
	return x * x
}

// 変数に関数を代入
let sq: Int -> Int = square // sq は「 Int を受けて Int を返す関数」型の変数
// 変数 sq に代入された関数を呼び出す
let result: Int = sq(3) // 9
```

### 高階関数

関数を引数に受けたり、戻り値として返したりする関数のことを ___高階関数___ （メソッドの場合は _高階メソッド_ ）と呼びます。

```swift
// 渡された x を関数 f に適用して println する高階関数
func applyAndPrint(x: Int, f: Int -> Int) {
	println(f(x))
}

applyAndPrint(3, square) // 9 （ 3 に square が適用される）
```

####  mapメソッド

`Optional<T>` の `map` メソッドは次のような _高階メソッド_ として宣言されています。

```swift
func map<U>(f: T -> U) -> U?
```

やや複雑ですが、これは「 `T` を受け取って `U` を返す関数」を引数に受け取るということです。 `map` メソッドに、さっきの関数 `square` を渡してみましょう。

```swift
let a: Int? = 3
a.map(square) // map メソッドの引数 f に関数 square を渡す → 結果は Optional(9)
```

この場合、 `a` の型は `Optional<Int>` 、 `square` の型は `Int -> Int` なので `map` メソッドの型は次のように解釈されます。

```swift:aにsquareを渡した場合のmapメソッドの型
func map(f: Int -> Int) -> Int?
```

`Optional` の `map` メソッドは次のような挙動をします。

- もし箱の中身が空（ `nil` ）だったら空の箱（ `nil` ）を返す。
- 箱に値が入っていたら、その値を渡された関数 `f` に適用する。そして、適用した結果を新しい箱に詰めて返す。

先程の `square` の例では、 `a` の箱には `3` が入っているので、 `square` に `3` が渡され `9` が得られます。そして、それが `Optional` に包まれて `return` されます。

### クロージャ

関数 `square` と `map` メソッドを使えば、箱から値を取り出さずに中身を二乗することができました。しかし、箱の中を操作する度にわざわざ関数を作るのは面倒です。 Swift には関数をその場で記述する構文 ___クロージャ___ があります[^3]。

例えば、 `func` を使って `square` を定義する代わりに、 _クロージャ_ を使って次のように書くことができます。

```swift
let square: Int -> Int = { (x: Int) -> Int in
	return x * x
}
```

_クロージャ_ のブロック内に式が一つだけ書かれている場合には、その式の結果が自動的に戻り値として使われます。そのため、 `return` を省略して次のように書けます。

```swift:returnを省略
let square: Int -> Int = { (x: Int) -> Int in  x * x }
```

また、 _クロージャ_ の宣言にも型推論が働くので、型宣言を省略して次のように書けます。

```swift:型宣言を省略
let square: Int -> Int = { x in  x * x }
```

さらに、引数名を省略することもできます。引数名を省略した場合は、第一引数が `$0` 、第二引数が `$1` 、…となります。

```swift:引数名を省略
let square: Int -> Int = { $0 * $0 }
```

`map` メソッドの引数に直接 _クロージャ_ を書くと次のようになります。

```swift
let result: Int? = a.map({ $0 * $0 })
```

### Trailing Closure

Swift では、関数やメソッドの引数として _クロージャ_ を渡す場合、最後の引数については _クロージャ_ を外出しして `if` や `for` のブロックのように書くことができます。

```swift
let result: Int? = a.map() { $0 * $0 }
```

また、その結果 `()` の中に書く引数がなくなった場合には、 `()` も省略することができます。

```swift:()を省略
let result: Int? = a.map { $0 * $0 }
```

これで、本節冒頭と同じシンプルなコードが得られました。

Optionalの考え方 (2)
----------------------------------------------------

次の問題に進む前に、 _Optional_ の別の側面について説明します。

### Optionalを使って失敗を表す

`String` の `toInt` メソッドは `String` を `Int` に変換するメソッドです。しかし、 `"abc"` のような文字列は `Int` としてパースすることができないので失敗します。失敗時には `Int` の代わりに `nil` が返されます。そのため、 __`toInt` の戻り値の型は `Int` ではなく `Int?` になります__。このことは大したことに思えないかもしれませんがとても重要です。

従来の _null参照_ の言語でも、関数やメソッドが処理に失敗したときに `nil` や `null` を返すことはよくあります。 Objective-C のライブラリはそのように設計されていますし、例外機構を持つ Java なんかでも失敗時に（例外ではなく） `null` が返ってくることも多いです。

Swift で `nil` が返された場合にそれらの言語と決定的に異なっているのは、 ___Optional_ は値を使う前に必ず `nil` かどうかチェックしなければならない__ ことです。

```swift
let numberOrNil: Int? = string.toInt()
if let number = numberOrNil { // そのままでは使えないので分岐
	// パースに成功したときの処理
} else {
	// パースに失敗したときの処理
}
```

Objective-C や Java では `nil` や `null` を返すメソッドに対して、失敗した場合の処理を無視しても問題なくコンパイルできます。そのため、意図しないエラー処理忘れが頻発し、多くのバグを生み出してきました。 ___null参照_ を排除して _Optional_ を導入することで、プログラマにエラー処理を強制し、そのようなバグを未然に防ぐことができるのです__。

- _Optional_ は単に `nil` を入れられるというだけでなく __失敗かもしれない値を表す__ ことがある。
- 失敗かもしれない値を _Optional_ で表すことで __エラー処理を強制することができる__。

上記の二点を意識して、 _Optional_ を見たときには失敗とエラー処理を意図しているのかもしれないという視点で見てみましょう。

箱の中身を操作する（失敗するかもしれない場合）
----------------------------------------------------

> _2._ `array: [Int]?` があるとき、 `array` の最初の要素を取得したい。ただし、 `array` が `nil` か、最初の要素が存在しない（ `Array` が空の）場合は `nil` を得たい。（ヒント：  `[Int]` は `first: Int?` というプロパティを持つ。 `first` は最初の要素が存在しない場合は `nil` を返す。）

この問題が 1 と違うのは、箱の中身に対する処理が失敗するかもしれないことです。もしこれを `map` を使って書こうとすると、次のように得られる結果が二重の箱（ `Int??` ）になってしまいます。

```swift
// first の型は Int?
// map は値を Optional で包みなおして返すので Optional が二重になる
let result: Int?? = array.map { $0.first }
```

Swift には、このようなケースを扱うための構文 _Optional chaining_ があります。これを使えば 2 の答えは簡単に書けます。

```swift:2の解答
let result: Int? = array?.first
```

しかし、 3 のようなケースでは _Optional chaining_ でうまく書くことができません。

> _3._ `x: Double?` があるとき、 `x` の平方根を計算したい。ただし、 `x` が `nil` または負の数の場合は `nil` を得たい。なお、 `sqrt` を安全にした（負の数を渡すと `nil` を返す）関数 `safeSqrt: Double -> Double?` があるものとして考えて良い。

2 と 3 は、箱の中身に対して失敗するかもしれない処理をしたいという意味では同じです。しかし、 _Optional chaining_ は、箱の中身に対してメソッドをコールすることはできても、箱の中身を引数に渡すことはできません。

とりあえず、箱が二重になってしまいますが `map` で書いてみると次のようになります。

```swift
let result: Int?? = x.map { safeSqrt($0) } // 箱が二重になる以外はうまく動く
```

今、二重の箱が邪魔なので外側の箱だけ開けたいです。でも `!` で開けるわけにはいきません。もし外側の箱が空（ `nil` ）だったらクラッシュしてしまうからです。

そこで `??` を使います。 `??` は `!` 同様に箱を空けますが、箱が空だった場合には代わりの値で代用します。 `a ?? b` と書くと、 `a` が `nil` でなければ `a` の箱の中身を、 `nil` だった場合には `b` を返します。

```swift:??の使い方
// 結果の型が Int? ではなく Int なことに注意
let result1: Int = "2".toInt() ?? -1 // 2
let result2: Int = "X".toInt() ?? -1 // -1
```

`??` は箱を一つ開けるので、 `??` を使えば二重の箱を一重にすることができます。

```swift:3の解答(1)
// 結果の型が Int?? ではなく Int? なことに注意
let result: Int? = x.map { safeSqrt($0) } ?? nil
```

### flatMap

このような処理（ `map` の結果の二重の箱を一重にしたい ）はよく行われるので __`flatMap` というメソッドが用意されています__[^5]。

`flatMap` を使えば 3 の解答は次のように書けます。

```swift:3の解答(2)
a.flatMap { safeSqrt($0) }
```

よりシンプルになりました。しかし、実はもっとシンプルに書くこともできます。

```swift:3の解答(3)
a.flatMap(safeSqrt)
```

`map { ... }` や `flatMap { ... }` の書き方に慣れてくるとどんな場合でもクロージャで `{ ... }` と書いてしまいがちですが、箱の中身に適用したい関数がすでに存在しているなら、単にその関数を渡せば良いのです[^6]。高階関数の説明で `a.map(square)` と書いたのと同じです。

### flatMapの役割

`Optional` の `flatMap` は失敗するかもしれない連続した処理を書く場合に役に立ちます。

_Optional chaining_ は同じ目的で使われますが、 3 の解答で見たように `flatMap` は _Optional chaining_ でうまく書けないケースにも対処できます。逆に _Optional chaining_ で書けるケースはすべて `flatMap` で書くことができます。

```swift
// 次の二つは等価
foo()?.bar()?.baz()?.qux() // foo, bar, baz, qux のどこかで失敗したら nil が返る
foo().flatMap { $0.bar() }.flatMap { $0.baz() }.flatMap { $0.qux() }

// Optional chaining では書けないケース
foo().flatMap { bar($0 * $0) }.flatMap { baz($0 + 1) }
```

__<em>Optional chaining</em> は `flatMap` の一部のケースを簡単に書くためのシンタックスシュガー__ だと考えておくとわかりやすいです。


複数の箱の中身を使う
----------------------------------------------------

> _4._ `a: Int?` と `b: Int?` があるとき、 `a + b` を計算したい。ただし、 `a` か `b` が `nil` の場合には `nil` を得たい。

この問題を解くには、二つの箱の中身を使って計算をする必要があります。箱を空けずに中身を使いたいので `map` で書いてみましょう。

```swift
let result: Int?? = a.map { a0 in b.map { b0 in a0 + b0 } }
```

二つの箱の中身を取り出すために `map` を入れ子にして使っています。この場合は 2 や 3　とは違って処理（足し算）は失敗はしませんが、 `map` を二重の入れ子にしたために結果も二重の箱（ `Int??` ）になってしまっています。

### flatMap

二重の箱をフラット（一重）にするために、ここでも `flatMap` が役に立ちます。

```swift:4の解答(1)
let result: Int? = a.flatMap { a0 in b.map { b0 in a0 + b0 } }
```

今、入れ子の内側が `flatMap` ではなく `map` になっていますが、これは `a0 + b0` が失敗しない処理だからです。失敗する処理をしたい場合には内側の `map` も `flatMap` でなければなりません。

例えば、 `safeSqrt` と同じように安全な `func safePow(x: Double, y: Double) -> Double?` を考えます[^14]。その場合、 `a: Double?` と `b: Double?` に対して `safePow` を計算するには次のようにします。

```swift
a.flatMap { a0 in b.flatMap { b0 in safePow(a0, b0) } }
```

より多くの `Optional` を使って何らかの処理を行いたい場合は、その分だけ `flatMap` を入れ子にすれば良いです。

```swift
// a, b, c が Int?
a.flatMap { a0 in b.flatMap { b0 in c.map { c0 in a0 + b0 * c0 } } }
```

### アプリカティブスタイル

`flatMap` の入れ子はやや複雑に思えるかもしれません。 _アプリカティブスタイル_ を使うとよりシンプルに書くことができます。

```swift:4の解答(2)
let result: Int? = (+) <%> a <*> b
```

_アプリカティブスタイル_ については本題から外れてしまうのでここでは説明しません。アプリカティブスタイルの使い方については ["まだSwiftyJSONで消耗してるの？#アプリカティブスタイル"](http://qiita.com/koher/items/300d89136b515291dac4#%E3%82%A2%E3%83%97%E3%83%AA%E3%82%AB%E3%83%86%E3%82%A3%E3%83%96%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB) に、実装の仕方については ["Swiftでアプリカティブスタイル"](http://qiita.com/koher/items/95583f58a443f6a33c28) により詳しい説明があります。 Swift でアプリカティブスタイルを使うには、 [thoughtbot/Runes](https://github.com/thoughtbot/runes) を使うのが一般的です。

モナドとしてのOptional
----------------------------------------------------

Swift の `Optional` は ___モナド___ です。

_モナド_ とは何でしょうか。 _モナド_ の定義[^7]を読んでも圏論を知らないと理解するのは難しいです。[プログラミングにおけるモナドについてはこちらで詳しく説明していますので御覧下さい。](http://qiita.com/koher/items/12f72f2fc2db7fa709cf)ここではその中から僕が一番しっくりきた説明[^8]を簡単に紹介します。

> モナドというのは、モナドでくるまれた中の世界ではモナドを気にせずに処理が記述でき、外からみるとモナドでくるまれているという、外と中を分離するための仕組みです。

_Optional binding_ （ `if let ...` ）や _Forced Unwrapping_ （ `!` ）を使って `Optional` の中身を取り出すのは、分離されている箱の中の世界と外の世界をつなげてしまう行為です。 __`map` や `flatMap` を使うことで、中と外を分離したまま中の世界に対する処理を記述することができる__ のです。

### Promise と比べてみる

`Optional` だけを見て _モナド_ をイメージするのは難しいので、他の _モナド_ と比較してみましょう。ここでは `Promise` という _モナド_ を取り上げます。

`Promise` は JavaScript でよく使われ、[次期 JavaScript にも正式採用された](http://www.html5rocks.com/ja/tutorials/es6/promises/)ので知っている人も多いかもしれません。 `Promise` は主に非同期処理で使われ、今はまだないけど将来的に得られる値を表します。

例えば、サーバと通信して値を取得したいとします。しかし、サーバからのレスポンスを待っていると、その間 UI が固まってしまうなどの問題があります。通常はコールバックで結果を受け取るのですが、それだとその値はコールバックの中でしか使えず、取り回すことができないので不便です。また、連続した非同期処理を書くときには、コールバックのネストがどんどん深くなってしまいます。

`Optional` が __「中身（値）が空かもしれない箱」__ なら、 `Promise` は、 __「今はまだないけど将来的に中身（値）が得られる箱」__ です。サーバ通信などの非同期処理を行う関数が、コールバックで結果を返す代わりに `Promise` という箱を返すことで、サーバレスポンスを待たずに結果を取り回すことができるようになります。

例を見てみましょう（ここでは、 `Promise` の `then` を `map` および `flatMap` として Swift で実装した [PromiseK](https://github.com/koher/PromiseK) を使います）。

```swift
// asyncFoo: String -> Promise<Int> はサーバと通信して Int を取得する関数
let result: Promise<Int> = asyncFoo("abc").map { $0 * $0 } // 得られた結果を二乗
```

上記のコードでは、 `asyncFoo` はサーバと通信をして非同期的に結果を取得しますが、戻り値の `Promise<Int>` は即座に返されます。その `Promise<Int>` に対して `map` メソッドを呼び出すことで、「今はまだない値」を二乗しています。実際には `map` に渡された関数（ここでは引数を二乗する関数）はサーバから結果が取得できたあとに実行されます。コールバックのようですが、 `map` はまだ値が存在しない値を二乗した結果を表す箱（ `Promise` オブジェクト）を返すことに注意して下さい。 `Promise` を使うことで、このように「今はまだない値」がまるで存在しているかのように扱うことができます。

では、 `Promise` のコードと `Optional` のコードを比べてみましょう。

```swift:Promise
// 非同期的に得られた結果を二乗
let a: Promise<Int> = asyncFoo("abc").map { $0 * $0 }

// 非同期的な処理を連続して行う（ JS の Promise の then 相当）
let b: Promise<Int> = asyncFoo("xyz").flatMap { asyncBar($0 * $0) }.flatMap { asyncBaz($0 + 1) }

// 二つの非同期的な処理結果を利用した計算
let sum: Promise<Int> = a.flatMap { a0 in b.flatMap { b0 in Promise(a0 + b0) } }
```

```swift:Optional
// 失敗するかもしれない処理の結果を二乗
let a: Optional<Int> = failableFoo("abc").map { $0 * $0 }

// 失敗するかもしれない処理を連続して行う
let b: Optional<Int> = failableFoo("xyz").flatMap { failableBar($0 * $0) }.flatMap { failableBaz($0 + 1) }

// 二つの失敗するかもしれない処理結果を利用した計算
let sum: Optional <Int> = a.flatMap { a0 in b.flatMap { b0 in Optional(a0 + b0) } }
```

二つのコードは `Promise` と `Optional` が違うだけでそっくりですね！ __<em>モナド</em> という共通の性質を備えているから `Promise` と `Optional` は同じ方法で扱うことができる__ のです。

`map` や `flatMap` を使った書き方は一見難しそうに見えるかもしれません。しかし、一度慣れてしまえば、 `Optional` に限らず他の _モナド_ も統一的な方法で扱うことができるようになり、便利でわかりやすいものです。是非 `map` と `flatMap` を習得して下さい。

その他のモナドの例としては、 `Either` について ["Swift 3.0で追加されそうなEitherについて"](http://qiita.com/koher/items/288f01cddb0bbb6aa4e1) を書いたので御覧下さい。

ArrayとOptional
----------------------------------------------------

ここでは、 _Optional_ の別の顔について説明します。

実は `Array` を使えば `Optional` を表すことができます。 `Optional` は中身が空かもしれない箱でした。別の見方をすれば、 `Optional` を最大で一つしか要素を入れられない `Array` と考えることができます。

`Optional` を使った次のようなコードを考えます。

```swift:Optional
let a: Optional<Int> = 3
let b: Optional<Int> = a.map { $0 * $0 } // Optional(9)

let c: Optional<Int> = nil
let d: Optional<Int> = c.map { $0 * $0 } // nil

let sum: Optional<Int> = a.flatMap { a0 in b.flatMap { b0 in a0 + b0 } } // Optional(12)
```

これを `Array` で書き直してみましょう。

`Array` も _モナド_ なので[^9]、 `map` や `flatMap` を使うことができます。

```swift:Array
let a: Array<Int> = [3]
let b: Array <Int> = a.map { $0 * $0 } // [9]

let c: Array<Int> = []
let d: Array <Int> = a.map { $0 * $0 } // []

let sum: Array <Int> = a.flatMap { a0 in b.flatMap { b0 in [a0 + b0] } } // [12]
```

このように考えると、 __`Optional` はコレクションの仲間__ とも考えられます。正規表現で `?` が `0` 回か `1` 回の繰り返しを表すのに似ていますね！


箱の中身を使うけど結果は必要ないとき
----------------------------------------------------

> _5._ `a: Int?` があるとき、 `a` の値を `print` で表示したい。ただし、 `a` が `nil` の場合には何も表示したくない。

この問題は `map` を使えば簡単に解けます。

```swift:5の解答(1)
a.map { print($0) }
```

このとき、 `map` の戻り値の型はどうなっているでしょうか？ `print` の戻り値の型は `Void` なので、 `map` の戻り値の型は `Void?` になります。そのため、次のようなコードは正しく実行されます。

```swift
let a: Int? = 3
let result: Void? = a.map { print($0) } // Optional(())
```
Swift の `Void` は `()` （空のタプルの型）のシンタックスシュガーなので、 `Void` 型の値は `()` （空のタプル）になります。それが `Optional` に入っているので `result` は `Optional(())` となります。


今回の処理では `map` の戻り値は必要ないので、 `Optional(())` を返しているのはなんとなく不細工ですね。

`Array` には `map` の戻り値がないバージョンである `forEach` というメソッドがあります。

```swift
[2, 3, 5].forEach { print($0) } // 各要素を表示して改行
```

前節の通り `Optional` を要素数が最大 1 個のコレクションだと考えると、 `Optional` に `forEach` メソッドがあってもおかしくはありません。  `forEach` メソッドを [_Extension_ で実装しておけば](https://github.com/koher/swiftf/blob/9b52143aaca8d33d3a5987ed1231a5b38912c0e2/Project/swiftf/swiftf.swift#L17-L19) 5 の解答は次のように書けます。

```swift:5の解答(2)
a.forEach { print($0) }
```

`map` だと値を変換する意味合いが強いですし、 Swift 2.0 からは `map` の戻り値を使わないと警告が出るようになってしまいました。このようなケースではコードの意図を明確化するために、また、警告を回避するために、僕は `forEach` を使うようにしています。

UnionとしてのOptional
----------------------------------------------------

### CeylonのOptional

[Ceylon](http://ceylon-lang.org/) （という言語）では _Optional type_ の実装がユニークです。 Ceylon の _Optional type_ は ___Union type___ を使って実現されています。

_Union type_ [^11]とは、例えば、 `Integer|String` というように、 `Integer` か `String` のどちらかを表すというような型です。

```ceylon:Ceylon
Integer|String a = 123; // Integer も代入できる
Integer|String b = "abc"; // String も代入できる
```

当然、 `Integer|String` のままでは `Integer` や `String` として使うことはできません。

```ceylon:Ceylon
Integer|String a = 3;
Integer b = a * a; // コンパイルエラー → このままでは Integer として使えない
```

`a` を `Integer` として使うには次のようにします。

```ceylon
Integer|String a = 3;
if (is Integer a) { // このブロックの中では a は Integer として使える
	Integer b = a * a; // 9
}
```

Ceylon の `Integer?` は `Optional<Integer>` ではなく `Integer|Null` のシンタックスシュガーです。 `Null` は唯一のインスタンス `null` を持つクラスで、何のメソッドも持ちません。そのため、 `Integer|Null` のままでは何のメソッドも呼び出すことができません[^12]。

```ceylon:Ceylon
Integer? a = 3; // Integer|Null と等価
Integer? result;
if (is Integer a) { // このブロックの中では a は Integer として使える
	result = a * a;
} else {
	result = null;
}
```

Swift の _Optional binding_ （ `if let ...` ）そっくりですね！このように、 `Optional<T>` という型を導入しなくても、 _Union type_ を使ってシンプルに _Optional_ を実現することができます。

### SwiftのOptional

実は、 Swift の `Optional` はこれに近い仕様になっています。 Swift では `Optional` は `enum` を使って次のように宣言されています（ただし、話の本題に関係ない部分は省略しています）。

```swift:Swift
enum Optional<T> {
    case None
    case Some(T)
}
```

`enum` は列挙された中のどれか一つを値として持つので、 `Optional` 型の変数は `None` （ `nil` に相当）か `Some` を値として持つことになります。また、 Swift の `enum` は _Associated value_ と呼ばれる値を関連付けることができるため、 `Some` は `T` 型の値を持つことができます。これは（ `Some` というタグを無視してしまえば）、 `T|None` という構造です。

_Union type_ で `Optional` を実装する利点の一つとして、 `Foo?` に `Foo` 型の値をそのまま代入できることが挙げられます。 `Foo|Bar` 型の変数に `Foo` や `Bar` の値を代入できるのは当然なので、 `Foo|Null` 型の変数に `Foo` を代入できるのも当たり前です。

```ceylon:Ceylon
Integer? a = 3 // a は Integer|Null なので Integer を代入できるのは当たり前
```

しかし、 `Optional<Foo>` に `Foo` を代入できるのは不自然に思えます。実際、 Java ではこれはエラーになります。

```java:Java
Optional<Integer> a = 3; // コンパイルエラー
Optional<Integer> b = Optional.of(3); // Optional で包む必要あり
```

Swift ではなぜか `Optional<Foo>` に `Foo` をそのまま代入することができます。

```swift:Swift
let a: Optional<Int> = 3 // OK → Int|None っぽい挙動
```

しかし、自分で `Optional` のような `enum` を実装して同じことをするとコンパイルエラーになります。

```swift:Swift
enum MyOptional<T> { // 自作 Optional
    case None
    case Some(T)
}

let a: MyOptional<Int> = 3 // コンパイルエラー
let b: MyOptional<Int> = .Some(3) // Optional で包む必要あり
```

Java のときと同じですね！

どうやら、現時点では `enum` を _Union type_ のように振る舞わせる機能は `Optional` や `ImplicitUnwrappedOptional` に限定されているようです[^13]。

しかし、 _Union type_ は Ceylon に限らず、 [TypeScript への導入が計画されていたり](https://github.com/Microsoft/TypeScript/wiki/Roadmap)、（ Facebook がリリースした AltJS の） [flow](http://flowtype.org/) では[すでに採用されています](http://flowtype.org/docs/union-intersection-types.html)。 _Union type_ は _Optional type_ と共に最近のプログラミング言語の潮流の一つだと思うので、将来的に Swift でも採用されるかもしれません。そして、 `Optional` との一貫性を考えると、 `enum` がその役割を果たすようになるのではないでしょうか。

`Optional` が _Union type_ っぽく振る舞う性質のおかげで、「力試し」の 4 の解答は明示的に `Optional` に包む必要がないと考ることもできます。


```swift
// flatMap に渡す関数は Int? を return しなければならないので
// 本来はこのように Optional に包んで return しないといけないが、
a.flatMap { a0 in b.flatMap { b0 in Optional(a0 + b0) } }

// Int? を Int|None のように考えると
// Int|None を返さないといけないところで
// Int を返せるのは当たり前なのでので
// Optional で包まずに return できる
a.flatMap { a0 in b.flatMap { b0 in a0 + b0 } }
```

### Union typeとサブタイピング

スーパータイプ、サブタイプと聞くとクラスの継承を思い浮かべる人が多いと思います。しかし、 _Union type_ もスーパータイプ、サブタイプの関係を作ります。

`Animal` クラスを継承した `Cat` クラスがあるとき、 `Animal` は `Cat` のスーパータイプなので次のような代入が可能です。

```swift:Swift
let animal: Animal = Cat() // Animal は Cat のスーパータイプ
```

同様に、 `Integer|String` 型変数に `Integer` や `String` を代入できるというのは、 `Integer|String` が `Integer` や `String` のスーパータイプとして振舞うということです。

```ceylon:Ceylon
Integer|String a = 123; // Integer|String は Integer のスーパータイプ
```

_Union type_ が本当にスーパータイプであるかを確かめるにはどうすれば良いでしょうか。

クラスを継承してメソッドをオーバーライドするとき、戻り値の型をサブタイプに狭めることができます。

```swift:Swift
class Foo {
	func foo() -> Animal {
		return Animal()
	}
}

class Bar : Foo {
	override func foo() -> Cat { // 戻り値の型を Cat に狭める
		return Cat()
	}
}
```

もし、 `Integer` が `Integer|String` のサブタイプであれば、同様のことができるはずです。次の Ceylon のコードは問題なく実行できます。

```ceylon:Ceylon
class Foo() {
    shared default Integer|String foo() {
    	return 123;
    }
}

class Bar() extends Foo() {
    shared actual Integer foo() { // 戻り値の型を Integer に狭める
    	return 456;
    }
}
```

同じことが　_Optional type_ にも言えるはずです。 Swift の `Optional` で次のコードを書くと正しく実行できます。

```swift
class Foo {
	func foo() -> Optional<Int> {
		return 123
	}
}

class Bar : Foo {
	override func foo() -> Int { // 戻り値の型を Int に狭める
		return 456
	}
}
```

これは `Optional<Int>` が `Int` のスーパータイプとして振舞っている証拠です。当然ですが、自作の `MyOptional` で同じことをやるとコンパイルエラーになります。ますます、 Swift の `Optional` は _Union type_ っぽいですね！

「力試し」の回答者
----------------------------------------------------

僕が把握している限り、次のお二人が「力試し」にチャレンジして投稿して下さいました。 @Ushio@github さんの方法は `flatMap` と等価で、 @sora0077@github さんの方法は `map` と `??` を組み合わせた方法になっています。

- [力試し：SwiftのOptionalでこれできますか？　にチャレンジ](http://qiita.com/Ushio@github/items/1410eaba5898a79b4516) by @Ushio@github さん
- [力試し：SwiftのOptionalでこれできますか？　に挑戦](http://qiita.com/sora0077@github/items/dd1e1429e73fee193788) by @sora0077@github さん

まとめ
----------------------------------------------------

- _Optional_ は「10億ドルの誤り」を回避する素晴らしい仕様
- しかし、 _Optional_ を使って書きづらいケースがある
- `Foo?` ではなく `Optional<Foo>` だと考えればわかりやすい
- _Optional_ は「中身（値）が空かもしれない箱」と考えると良い
- `map` や `flatMap` を使えばそのようなケースにエレガントに対処できる
- その背景には _モナド_ という概念があり、 `Optional` に限らない他の _モナド_ も含めて統一的に扱える
- `Optional` は要素数が 0 か 1 のコレクションとして考えることもできる
- `Optional` は _Union type_ の一種として考えることもできる

_Optional_ の背景にあるこれらの概念や考え方を理解しておくことで、思考が整理され _Optional_ を使うときの見通しがよくなります。 `map` や `flatMap` を使いこなして安全で楽しい _Optional_ ライフを送りましょう！

[^1]: ["アントニー・ホーア - Wikipedia"](http://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%B3%E3%83%88%E3%83%8B%E3%83%BC%E3%83%BB%E3%83%9B%E3%83%BC%E3%82%A2#.E8.AA.9E.E9.8C.B2) より。

[^2]: 便宜的に `nil` を `Optional` 型の値として説明していますが、厳密には[Swiftにnilという値は存在しません](http://qiita.com/koher/items/cbe232782b9943715c9b)。

[^3]: Swift の _クロージャ_ は他の言語で言う _ラムダ式_, _関数リテラル_, _無名／匿名関数_ などに当たります。必ずしも状態を保持しているわけではありません。

[^5]: `flatMap` の他に `bind` などと呼ばれたりもします。 Haskell では `>>=` という演算子で表します。

[^6]: ですので、 `flatMap` を使わない場合の解答は `x.map(safeSqrt) ?? nil` とも書けます。

[^14]: 例えば、 $-1.0^{0.5}$ などは実数の範囲で解を持ちません。

[^7]: _モナド_ の定義は[こちら](http://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%8A%E3%83%89_%28%E5%9C%8F%E8%AB%96%29)にあります。

[^8]: ["Java8でのプログラムの構造を変えるOptional、ただしモナドではない - きしだのはてな"](http://d.hatena.ne.jp/nowokay/20130524) より。なお、 Java 8 の `Optional` は[最終仕様では _モナド_ になりました](http://d.hatena.ne.jp/nowokay/20130805)。

[^9]: `Array` を _モナド_ として考えた場合、どのような箱としてイメージすればよいかは今度書きたいと思います。

[^11]: 「または」ではなく「かつ」を表す _Intersection type_ （ `Foo&Bar` ）もあって面白いです。関数の型を _Intersection type_ で表すことでオーバーロードを表現することができたりします。

[^12]: 正確には、 `Integer` と `Null` の共通のスーパークラスが何のメソッドも持たないからです。

[^13]: また、 Swift にはジェネリックな型の [_Variance_](http://qiita.com/koher/items/7dea63e0ce52ebda9873#hello-variance) を提供する仕組みも欠けています。 `Array` や `Optional` は [_Covariant_ です](http://qiita.com/koher/items/81767a345d5ed53c04b7)が、自作の型を　_Covariant_ や _Contravariant_ にすることはできません。