CTMacUser
CTMacUser

Reputation: 2052

Can't invoke generic initializer from protocol extension in Swift

I'm trying to call a struct I made from a protocol extension method I also made:

public struct AdjacentDifferenceArrayGenerator<T: Strideable where T.Stride == T>: GeneratorType {
    private var array: [T]
    public init<U: SequenceType where U.Generator.Element == T>(source: U) {
        self.array = source.adjacentDifference()
    }
    public mutating func next() -> [T]? {
        guard !array.isEmpty else {
            return nil
        }
        defer {
            self.array = self.array.adjacentDifference()
        }
        return self.array
    }
}

public extension SequenceType where Generator.Element: Strideable {
    public func adjacentDifference() -> [Self.Generator.Element.Stride] {
        var result: [Self.Generator.Element.Stride] = []
        var generator = AdjacentDifferenceGenerator(generator: self.generate())
        while let difference = generator.next() {
            result.append(difference)
        }
        return result
    }
}

public extension SequenceType where Generator.Element: Strideable, Generator.Element.Stride: Strideable, Generator.Element.Stride.Stride == Generator.Element.Stride {
    public func pyramidOfAdjacentDifferences() -> [[Self.Generator.Element.Stride]] {
        var result: [[Self.Generator.Element.Stride]] = []
        var array = self.adjacentDifference()
        while !array.isEmpty {
            result.append(array)
            array = array.adjacentDifference()
        }
        //var generator = AdjacentDifferenceArrayGenerator(source: self)
        //while let differences = generator.next() {
            //result.append(differences)
        //}
        return result
    }

The four lines that are commented near the end, after the substitute algorithm, are trying to use the same algorithm as the method in the first extension. When I uncomment out the first of those lines, the cursor waits at "AdjacentDifferenceArrayGenerator" and says: "Cannot invoke initializer for type 'AdjacentDifferenceArrayGenerator<_>' with an argument list of type '(source: Self)'" That last "Self" is capitalized in the error message although it's uncapitalized in code. Adding an explicit template bracket between the type and initializer arguments didn't help. Any ideas?

Upvotes: 0

Views: 144

Answers (1)

CTMacUser
CTMacUser

Reputation: 2052

I got around it by taking out the first iteration:

public extension SequenceType where Generator.Element: Strideable, Generator.Element.Stride: Strideable, Generator.Element.Stride.Stride == Generator.Element.Stride {
    public func pyramidOfAdjacentDifferences() -> [[Self.Generator.Element.Stride]] {
        var result = [self.adjacentDifference()]
        if result.first!.isEmpty {
            return []
        }

        var generator = AdjacentDifferenceArrayGenerator(source: result.first!)
        while let differences = generator.next() {
            result.append(differences)
        }
        return result
    }
}

I have to test if that first iteration result is legitimate, since taking it out of the loop means I lost the automatic check. I don't know if using "self" was the problem, or it was using a generic sequence instead of a definitive array was the problem. Still need help here....

Upvotes: 0

Related Questions