Swift 2.0で再帰的Enumがサポートされる！？


WWDC 2015のSwift関連の[発表資料](https://developer.apple.com/videos/wwdc/2015/?id=106)を眺めていたら，待望のRecursive EnumがSwift 2.0で追加されるようですね．同2.0で追加されたswitch以外でのenumパターンマッチと組み合わせると，Associated Enumの使い勝手がかなりよくなると思われます．（残念ながら現時点のXcode 7 betaでは，この機能はまだ実装されておらず実際に試すことができません．）
ちょっとフライング気味ですが，どんな感じになるのかだけでも見てみたいと思います．

__<追記 (2015/07/22)>：__　Xcode 7 beta4 でサポートされました．ただし，パターンマッチを`switch`文以外で使うとコンパイラが落ちます．

　
### 再帰的Enum
関数型言語でよく使うリスト構造は再帰的enumで定義すると以下のように書ける（ようになるはず？）．

```swift
enum List<T> {
    case Nil
    indirect case Cons(T, List<T>)
}

let xs: List<Int> = .Cons(1, .Cons(2, .Cons(3, .Cons(4, .Nil))))
```
`indirect`というキーワードは，タプル内の要素を参照型と見なせという指示なのでしょうかね．f
コンパイラは今までも再帰を認識できてたので，別にこのキーワードがなくても良さそうな気がしますが，人間にとってのアノテーションの意味合いがあるのかもしれませんね．
　
### パターンマッチを使いまくる
Swift 2.0ではswitch文以外，while, for, if文等でも[enumのパターンマッチ](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Patterns.html#//apple_ref/doc/uid/TP40014097-CH36-ID419)が使えるようになりました．
これらを使ってListに関数を追加していきましょう．
Haskellの定番パターンマッチ(`x:xs`)に習って`.Cons(x, xs)`をパターンとして使います．

```swift
extension List {
    func toArray() -> [T] {
        var list = self
        var array: [T] = []
        while case let .Cons(x, xs) = list {
            array.append(x)
            list = xs
        }
        return array
    }
}
```
whileの中にswitchを書かずに条件の所でパターンマッチ一発で要素(xとxs)を取り出せるので，以前と比べて大分すっきりと記述できるようになったと思いませんか？
ちなみに，Swift 2.0では内部関数でも再帰が使えるようになったので，whileの代わりに末尾再帰な内部関数を定義してやる方法もあります．

続いて定番のfilterとmap関数は再帰関数として，

```swift
extension List {
    func filter(pred: T -> Bool) -> List<T> {
        if case let .Cons(x, xs) = self  {
            if pred(x) {
                return .Cons(x, xs.filter(pred))
            }
            return xs.filter(pred)
        }
        return .Nil
    }
    
    func map<U>(f: T -> U) -> List<U> {
        guard case let .Cons(x, xs) = self else {
            return .Nil
        }
        return .Cons(f(x), xs.map(f))
    }
}
```
とこんな感じになります．mapの方はguardを使って早期脱出にしてみました．guardを使うとネストが浅くなって良さげです．
　
### ＜参考＞ Swift 1.2 でのやり方
比較のために，Swift 2.0以前の書き方を載せておきます．
といっても，参照型(class)だけでリストを定義するとパターンマッチが使えず全く面白くないので，enum+参照型の定義を使ったやり方です．

```swift
class Ref<T> {
    let val: T
    init(_ v: T) { val = v }
}

enum List<T> {
    case Nil
    case Cons(Ref<T>, Ref<List<T>>)
}

func cons<T>(x: T, xs: List<T>) -> List<T> {
    return .Cons(Ref(x), Ref(xs))
}
```
今まではAssociated Enumの要素を参照型でラップしてやることで再帰的enumを定義していました．面倒くさいですね...

```swift
extension List {
    func toArray() -> [T] {
        var list = self
        var array: [T] = []
        while true {
            switch list {
            case .Nil:
                return array
            case let .Cons(x, xs):
                array.append(x.val)
                list = xs.val
            }
        }
    }

    func map<U>(f: T -> U) -> List<U> {
        switch self {
        case .Nil:
            return .Nil
        case let .Cons(x, xs):
            return cons(f(x.val), xs.val.map(f))
        }
    }

    func filter(pred: T -> Bool) -> List<T> {
        switch self {
        case .Nil:
            return .Nil
        case let .Cons(x, xs):
            if pred(x.val) {
                return cons(x.val, xs.val.filter(pred))
            }
            return xs.val.filter(pred)
        }
    }
}
```
switchだらけな上，パターンマッチ後に参照から値を取り出す(.val)必要があリ，見た目がいまいちすっきりしない気がします．