Skip to content

Instantly share code, notes, and snippets.

@atierian
Created December 26, 2023 18:40
Show Gist options
  • Save atierian/4aaacdd65ca6a281c9205fc9e0ceb425 to your computer and use it in GitHub Desktop.
Save atierian/4aaacdd65ca6a281c9205fc9e0ceb425 to your computer and use it in GitHub Desktop.
Example of parametric polymorphism from WWDC '22 Embrace Swift Generics
// https://developer.apple.com/videos/play/wwdc2022/110352/
/**
some
- holds a fixed concrete type
- guarantees type relationships
any
- holds an abrititray concreate type
- erases type relationships
*/
protocol Animal {
associatedtype Feed: AnimalFeed
func eat(_ food: Feed)
}
protocol AnimalFeed {
associatedtype CropType: Crop where CropType.Feed == Self
static func grow() -> CropType
}
protocol Crop {
associatedtype Feed: AnimalFeed where Feed.CropType == Self
func harvest() -> Feed
}
struct Farm {
func feed(_ animal: some Animal) {
let crop = type(of: animal).Feed.grow()
let produce = crop.harvest()
animal.eat(produce)
}
func feedAll(_ animals: [any Animal]) {
for animal in animals {
feed(animal)
}
}
}
struct Cow: Animal {
func eat(_ food: Hay) { }
}
struct Horse: Animal {
func eat(_ food: Carrot) { }
}
struct Chicken: Animal {
func eat(_ food: Grain) { }
}
struct Hay: AnimalFeed {
static func grow() -> Alfalfa { .init() }
}
struct Alfalfa: Crop {
func harvest() -> Hay { .init() }
}
struct Carrot: AnimalFeed {
static func grow() -> Root { .init() }
}
struct Root: Crop {
func harvest() -> Carrot { .init() }
}
struct Grain: AnimalFeed {
static func grow() -> Wheat { .init() }
}
struct Wheat: Crop {
func harvest() -> Grain { .init() }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment