Skip to content

Instantly share code, notes, and snippets.

@ajRiverav
Last active April 7, 2022 20:42
Show Gist options
  • Select an option

  • Save ajRiverav/9fcab7b44cd17c022afa6197f862fc4b to your computer and use it in GitHub Desktop.

Select an option

Save ajRiverav/9fcab7b44cd17c022afa6197f862fc4b to your computer and use it in GitHub Desktop.
Type erasure in Swift: Example using Sequence and AnySequence, which are provided by the Swift Standard Library
//
// DO NOT USE - WORK IN PROGRESS
//
import Foundation
// "A sequence is a list of values that you can step through one at a time. The most common way to iterate over the elements of a sequence is to use a for-in loop.", per the documentation.
// Let's say one wanted to iterate over the sequence of strings ["apple", "bird", "cake"], such that
// the following code prints each value:
for value in sequence {
print(value)
}
// Let's attempt to create the sequence:
let sequenceString: Sequence = Sequence(["apple", "bird", "cake"])
// The line above produces the error:
// 'Sequence' cannot be constructed because it has no accessible initializers
// Let's then try to specify the type of the sequence elements (which is string):
let sequenceString: Sequence<String> = Sequence(["apple", "bird", "cake"])
// The line above produces the error:
// Cannot specialize non-generic type 'Sequence'
// Why are we getting this errors?
// Upon inspection of `Sequence`, we see it is a protocol and has three requirements:
// 1) method makeIterator() -> Self.Iterator (Returns an iterator over the elements of this sequence)
// 2) associatedtype Iterator (A type that provides the sequence’s iteration interface and encapsulates its iteration state)
// 3) associatedtype Element (A type representing the sequence’s elements)
// Of interest if the last requirement. We can see that `Sequence` can handle different element types (via its associatedtype requirement) but -and this is key to understand- one cannot declare an instance of it as `Sequence<String>`, hence the compiler warning "Cannot specialize non-generic type 'Sequence'".
// So, what can one do? One option (the one that gives birth to the creation of `AnySequence`) is to create a new type which would allow one to implement protocol `Sequence`, including -and this is another key concept to understand- its associated type `Element`. The mechanics of this look like:
struct AnySequence: Sequence {
}
let sequenceString: Sequence<String> = Sequence(["apple", "bird", "cake"])
let anySequenceString: AnySequence<String> = AnySequence(["apple", "bird", "cake"])
let anySequenceInt: AnySequence<Int> = AnySequence([1, 2, 3])
print(anySequenceString)
// AnySequence<String>(_box: Swift._SequenceBox<Swift.Array<Swift.String>>)
print(anySequenceInt)
// AnySequence<Int>(_box: Swift._SequenceBox<Swift.Array<Swift.Int>>)
@ajRiverav

ajRiverav commented Apr 7, 2022

Copy link
Copy Markdown
Author

initial commit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment