[swift-evolution] Rethink about the SequenceType, GeneratorType and CollectionType
Susan Cheng
susan.doggie at gmail.com
Mon Jan 11 04:43:07 CST 2016
i find that IndexingGenerator is also causing circularity
2016-01-11 18:14 GMT+08:00 Susan Cheng <susan.doggie at gmail.com>:
> 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/7cf58274/attachment-0001.html>
More information about the swift-evolution
mailing list