public enum Stream: NilLiteralConvertible, SequenceType { case Nil indirect case Cons(A, Memo) public init(sequence: S) { self = Stream(generator: sequence.generate()) } public init(var generator: G) { self = Stream { generator.next() } } public init(_ f: () -> A?) { self = f().map { Stream.Cons($0, Memo { Stream(f) }) } ?? Stream.Nil } public var uncons: (first: A, rest: Memo)? { switch self { case let .Cons(first, rest): return (first, rest.value) default: return nil } return analysis(ifCons: { $0 }, ifNil: { nil }) } public var first: A? { return uncons?.first } public var rest: Stream { return uncons?.rest.value ?? .Nil } public var isEmpty: Bool { return uncons == nil } public func map(transform: A -> B) -> Stream { return uncons.map { first, rest in Stream.Cons(transform(first), Memo { rest.map(transform) }) } ?? Stream.Nil } public func concat(other: Stream) -> Stream { switch self { case .Nil: return other case let .Cons(first, rest): return .Cons(first, rest.map { $0.concat(other) }) } } public init(nilLiteral: ()) { self = .Nil } public func generate() -> AnyGenerator { var current = self return anyGenerator { let next = current.first current = current.rest return next } } }