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 func analysis(@noescape ifCons ifCons: (A, Memo) -> B, @noescape ifNil: () -> B) -> B { switch self { case let .Cons(first, rest): return ifCons(first, rest) case .Nil: return ifNil() } } public var uncons: (first: A, rest: Memo)? { return analysis(ifCons: { $0 }, ifNil: { nil }) } public var first: A? { return uncons?.first } public var rest: Memo { return analysis(ifCons: { $1 }, ifNil: { Memo(evaluated: .Nil) }) } public var isEmpty: Bool { return uncons == nil } public func map(transform: A -> B) -> Stream { return analysis( ifCons: { .Cons(transform($0), $1.map { $0.map(transform) }) }, ifNil: { 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 = Memo(evaluated: self) return anyGenerator { let next = current.value.first current = current.value.rest return next } } }