Xcode 6.1.1 (6A2008a)
iPhone Simulatorで動作確認しました。
// 追記 12/13
initを利用することで操作時に変数のキャプチャを気にする必要がなくなりました。
// 追記 12/14
ArrayLiteralConvertibleでの初期化を追加
enum ConsList<T: Printable> {
case Nil
case Cons(T, @autoclosure () -> ConsList<T>)
init(_ v: T, _ cons: ConsList<T>) {
let cons_ = cons // なくても問題なかったが念の為に束縛してみる
self = .Cons(v, cons_)
}
}
extension ConsList: ArrayLiteralConvertible {
typealias Element = T
init(arrayLiteral elements: Element...) {
var cons = ConsList.Nil
for e in reverse(elements) {
cons = ConsList(e, cons)
}
self = cons
}
}
extension ConsList: Printable {
var description: String {
switch self {
case .Nil:
return "Nil"
case .Cons(let v, let cons):
return v.description + " -> " + cons().description
}
}
}
main.swift
let cons = ConsList(1, ConsList("2", ConsList(3.4, .Nil)))
println(cons)
let source: [Int] = [1, 2, 3]
var cons2: ConsList<Int> = .Nil
for s in reverse(source) {
cons2 = ConsList(s, cons2) //これは取り出し時に無限ループしてしまう -> 追記によりこちらでも問題なくなった
//let child = cons2
//cons2 = ConsList.Cons(s, child)
}
println(cons2)
let cons3: ConsList = [1, "2", 3.4]
println(cons3)
//1 -> 2 -> 3.4 -> Nil
//1 -> 2 -> 3 -> Nil
//1 -> 2 -> 3.4 -> Nil
こちらの投稿を参考にしました。
Swiftのenumで、再帰的なデータ型は無理だった話し