Skip to content

Instantly share code, notes, and snippets.

@mhmdatallaa
Forked from rnapier/erasure.swift
Last active October 11, 2024 09:22
Show Gist options
  • Save mhmdatallaa/1839f4225553af56d0851d2c963dea8a to your computer and use it in GitHub Desktop.
Save mhmdatallaa/1839f4225553af56d0851d2c963dea8a to your computer and use it in GitHub Desktop.
A Little Respect for AnySequence (http://robnapier.net/erasure)
import Swift
/*:
A simple type-erased sequence
*/
let seq = AnySequence([1,2,3])
/*:
## Who Needs Types Like That?
*/
/*:
A not-so-simple, not-type-erased sequence
*/
let xs = [1,2,3]
let ys = ["A","B","C"]
let zs = zip(xs.reverse(), ys.reverse())
func reverseZip<T,U>(xs: [T], _ ys: [U]) -> Zip2Sequence<ReverseRandomAccessCollection<[T]>, ReverseRandomAccessCollection<[U]>> {
return zip(xs.reverse(), ys.reverse())
}
// Why do we need to change the signature, just to change the implementation?
func reverseZipRefactor<T,U>(xs: [T], _ ys: [U]) -> [(T,U)] {
return zip(xs, ys).reverse()
}
// This can handle either implementation
func reverseZipAny<T,U>(xs: [T], _ ys: [U]) -> AnySequence<(T,U)> {
return AnySequence(zip(xs, ys).reverse())
}
/*:
## Chains of Association
*/
protocol Animal {
associatedtype Food
func feed(food: Food)
}
// Kinds of Food
struct Grass {}
struct Worm {}
struct Cow: Animal {
func feed(food: Grass) { print("moo") }
}
struct Goat: Animal {
func feed(food: Grass) { print("bah") }
}
struct Bird: Animal {
func feed(food: Worm) { print("chirp") }
}
struct AnyAnimal<Food>: Animal {
private let _feed: (Food) -> Void
init<Base: Animal>(_ base: Base) where Food == Base.Food {
_feed = base.feed
}
func feed(food: Food) { _feed(food) }
}
let grassEaters = [AnyAnimal(Cow()), AnyAnimal(Goat())]
let grass = Grass()
for animal in grassEaters {
animal.feed(grass)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment