[swift-evolution] Rethink about the SequenceType,	GeneratorType and CollectionType
    Susan Cheng 
    susan.doggie at gmail.com
       
    Mon Jan 11 04:14:56 CST 2016
    
    
  
Jordan Rose has a thought in PermutationGenerator thread that about any
GeneratorType "is-a" SequenceType. (I missed the thread)
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160104/005525.html
So i get a graph with:
SequenceType -----------------------------------> CollectionType
        ∟ generate() ----> GeneratorType
if this correct, we will redefine the GeneratorType as SequenceType
/// Encapsulates iteration state and interface for iteration over a
/// *sequence*.
///
/// - Note: While it is safe to copy a *generator*, advancing one
///   copy may invalidate the others.
///
/// Any code that uses multiple generators (or `for`...`in` loops)
/// over a single *sequence* should have static knowledge that the
/// specific *sequence* is multi-pass, either because its concrete
/// type is known or because it is constrained to `CollectionType`.
/// Also, the generators must be obtained by distinct calls to the
/// *sequence's* `generate()` method, rather than by copying.
public protocol GeneratorType : SequenceType {
    /// The type of element generated by `self`.
    typealias Element
    /// Advance to the next element and return it, or `nil` if no next
    /// element exists.
    ///
    /// - Requires: `next()` has not been applied to a copy of `self`
    ///   since the copy was made, and no preceding call to `self.next()`
    ///   has returned `nil`.  Specific implementations of this protocol
    ///   are encouraged to respond to violations of this requirement by
    ///   calling `preconditionFailure("...")`.
    @warn_unused_result
    public mutating func next() -> Self.Element?
}
extension GeneratorType {
    public func generate() -> Self {
        return self
    }
}
and discard this(break circularity between SequenceType and GeneratorType):
extension SequenceType where Self.Generator == Self, Self : GeneratorType {
    public func generate() -> Self
}
also, adding the follows to stdlib:
public extension SequenceType where Self : Indexable {
    var startIndex: MultipassIndex<Generator> {
        var g = self.enumerate().generate()
        if let (idx, val) = g.next() {
            return MultipassIndex(reachEnd: false, index: idx, buffer: val,
generator: g)
        }
        return MultipassIndex(reachEnd: true, index: nil, buffer: nil,
generator: g)
    }
    var endIndex: MultipassIndex<Generator> {
        return MultipassIndex(reachEnd: true, index: nil, buffer: nil,
generator: self.enumerate().generate())
    }
    subscript(position: MultipassIndex<Generator>) -> Generator.Element {
        return position.buffer!
    }
}
// Note: Requires G has value semantics
public struct MultipassIndex<G: GeneratorType> : ForwardIndexType {
    public func successor() -> MultipassIndex {
        var r = self
        if !reachEnd, let (idx, val) = r.generator.next() {
            r.index = idx
            r.buffer = val
        } else {
            r.reachEnd = true
            r.index = nil
            r.buffer = nil
        }
        return r
    }
    var reachEnd: Bool
    var index: Int?
    var buffer: G.Element?
    var generator: EnumerateGenerator<G>
}
public func == <T>(x: MultipassIndex<T>, y: MultipassIndex<T>) -> Bool {
    return x.index == y.index
}
That means we can defined a collection as follows and implement Indexable
automatically:
struct Fib : CollectionType {
    typealias Generator = FibGenerator
    var a, b: Int
    func generate() -> FibGenerator {
        return FibGenerator(a: a, b: b)
    }
}
struct FibGenerator : GeneratorType {
    var a, b: Int
    mutating func next() -> Int? {
        let temp = a
        (a, b) = (b, a + b)
        return temp
    }
}
in this case, because of GeneratorType is clearly a destructive iteration
type and CollectionType is clearly a multi-pass indexed type
we should stop using the SequenceType (or just rename it to _SequenceType
and tell people don't use it directly) directly. we have the GeneratorType
which confirms SequenceType already. it can reduce
confusion of SequenceType.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160111/63d3505a/attachment.html>
    
    
More information about the swift-evolution
mailing list