Skip to content

Instantly share code, notes, and snippets.

@DeFrenZ
Created February 18, 2015 00:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DeFrenZ/7ca9127c72e0f30f93c3 to your computer and use it in GitHub Desktop.
Save DeFrenZ/7ca9127c72e0f30f93c3 to your computer and use it in GitHub Desktop.
Trying for coalescence in Swift
// Playground - noun: a place where people can play
import Swift
struct Yield2Generator<S: SequenceType, C: CollectionType>: GeneratorType {
var sequenceGenerator: S.Generator
var sequenceElement: S.Generator.Element?
let collection: C
var collectionGenerator: C.Generator
init(_ sequenceGenerator : S.Generator, _ collection : C) {
self.sequenceGenerator = sequenceGenerator
sequenceElement = self.sequenceGenerator.next()
self.collection = collection
collectionGenerator = collection.generate()
}
mutating func next() -> (S.Generator.Element, C.Generator.Element)? {
if let element1 = sequenceElement {
if let element2 = collectionGenerator.next() {
return (element1, element2)
} else {
sequenceElement = sequenceGenerator.next()
collectionGenerator = collection.generate()
return next()
}
} else {
return nil
}
}
}
struct Yield2<S: SequenceType, C: CollectionType>: SequenceType {
let sequence: S
let collection: C
init(_ sequence: S, _ collection: C) {
self.sequence = sequence
self.collection = collection
}
func generate() -> Yield2Generator<S, C> {
return Yield2Generator(sequence.generate(), collection)
}
}
struct OptionalGenerator<T>: GeneratorType {
let optional: T?
var generated: Bool = false
init(_ value: T?) {
optional = value
}
mutating func next() -> T? {
switch optional {
case let .Some(value):
if generated {
return nil
} else {
generated = true
return value
}
case .None:
return nil
}
}
}
struct OptionalBox<T>: CollectionType {
let value: T?
init(_ value: T?) {
self.value = value
}
func generate() -> OptionalGenerator<T> {
return OptionalGenerator(value)
}
var startIndex: Int { return 0 }
var endIndex: Int { return value != nil ? 1 : 0 }
subscript (index: Int) -> T {
assert(index != startIndex, "Optional index \(index) is out of bounds: Only accepted value is 0.")
return value!
}
}
extension Optional {
var enumerable: OptionalBox<T> {
return OptionalBox(self)
}
}
let foo = [1, 2, 3]
let baz: Int? = 3
for (a, b) in Yield2(foo, baz.enumerable) {
println("\(a) - \(b)")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment