Created
December 26, 2023 18:40
-
-
Save atierian/4aaacdd65ca6a281c9205fc9e0ceb425 to your computer and use it in GitHub Desktop.
Example of parametric polymorphism from WWDC '22 Embrace Swift Generics
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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