The compiler errors will tell you. I put your code in a playground and saw the following errors
Playground execution failed: MyPlayground.playground:15:1: error: type 'BookCollection' does not conform to protocol 'Indexable'
extension BookCollection: CollectionType
^
Swift.Indexable:6:15: note: unable to infer associated type 'Index' for protocol 'Indexable'
typealias Index : ForwardIndexType
^
Swift.CollectionType:2:12: note: inferred type 'Range<BookCollection.Index>' (by matching requirement 'subscript') is invalid: does not conform to 'ForwardIndexType'
public subscript (bounds: Range<Self.Index>) -> Slice<Self> { get }
^
MyPlayground.playground:15:1: error: type 'BookCollection' does not conform to protocol 'SequenceType'
extension BookCollection: CollectionType
^
Swift.SequenceType:35:17: note: protocol requires function 'generate()' with type '() -> Generator'
public func generate() -> Self.Generator
^
Swift.SequenceType:2:17: note: candidate has non-matching type '<`Self`> () -> `Self`' (aka '<τ_0_0> () -> τ_0_0')
public func generate() -> Self
^
Swift.SequenceType:5:17: note: candidate has non-matching type '<`Self`> () -> `Self`.Base.Generator' (aka '<τ_0_0> () -> τ_0_0.Base.Generator')
public func generate() -> Self.Generator
^
Swift.CollectionType:2:17: note: candidate has non-matching type '<`Self`> () -> IndexingGenerator<`Self`>' (aka '<τ_0_0> () -> IndexingGenerator<τ_0_0>')
public func generate() -> IndexingGenerator<Self>
Starting from the top, I see we need a type for the associated index type and then there is a whole load of errors that relate to it not being defined, so I add a typealias
for protocol Indexable in the extension and that gives me a whole load more errors, so I change CollectionType
to Indexable
temporarily
extension BookCollection: Indexable
{
typealias Index = Int
}
And now i have the following:
Playground execution failed: MyPlayground.playground:15:1: error: type 'BookCollection' does not conform to protocol 'Indexable'
extension BookCollection: Indexable
^
Swift.Indexable:21:15: note: protocol requires nested type '_Element'
typealias _Element
^
_Element
is supposed to be an implementation detail (it starts with an underscore), but let's roll with it for now and add a type alias for it too.
extension BookCollection: Indexable
{
typealias Index = Int
typealias _Element = Book
}
Now I have the following
Playground execution failed: MyPlayground.playground:15:1: error: type 'BookCollection' does not conform to protocol 'Indexable'
extension BookCollection: Indexable
^
Swift.Indexable:12:16: note: protocol requires property 'startIndex' with type 'Index' (aka 'Int')
public var startIndex: Self.Index { get }
^
Swift.Indexable:20:16: note: protocol requires property 'endIndex' with type 'Index' (aka 'Int')
public var endIndex: Self.Index { get }
^
Swift.Indexable:22:12: note: protocol requires subscript with type 'Index -> _Element'
public subscript (position: Self.Index) -> Self._Element { get }
So now I implement the two properties and the subscript. I notice that implementing the subscript would allow the compiler to infer the two type alias types so I can delete those declarations.
extension BookCollection: Indexable
{
var startIndex: Int { return books.startIndex }
var endIndex: Int { return books.endIndex }
subscript(index: Int) -> Book
{
return books[index]
}
}
This gives no errors, so we change the protocol back to CollectionType
and we still have no errors so we must be done.