Skip to content

Instantly share code, notes, and snippets.

@rayfix
Created March 6, 2016 13:31
Show Gist options
  • Save rayfix/f81606710731f6bd6059 to your computer and use it in GitHub Desktop.
Save rayfix/f81606710731f6bd6059 to your computer and use it in GitHub Desktop.
Pokemon Type Erasure (take 2)
//: Second Type Erasure
import Foundation
protocol Pokemon {
typealias Power
func attack(power: Power)
}
private class _AnyPokemonBoxBase<Power>: Pokemon {
func attack(power: Power) {
fatalError()
}
}
private class _AnyPokemonBox<P: Pokemon>: _AnyPokemonBoxBase<P.Power> {
typealias Power = P.Power
let base: P
init(_ base: P) {
self.base = base
}
override func attack(power: Power) {
base.attack(power)
}
}
final class AnyPokemon<Power>: Pokemon {
private let box: _AnyPokemonBoxBase<Power>
init<P: Pokemon where P.Power == Power>(_ base: P) {
self.box = _AnyPokemonBox(base)
}
func attack(power: Power) {
box.attack(power)
}
}
struct Electric {
var charge: Int = 0
func spark() {
print("Spark: ", Array(count: charge, repeatedValue: "⚡️").joinWithSeparator(""))
}
}
class Pikachu : Pokemon {
func attack(power: Electric) {
power.spark()
}
}
struct Fire {
var level: Int = 0
func blast() {
print("Blast: ", Array(count: level, repeatedValue: "🔥").joinWithSeparator(""))
}
}
class Charmander: Pokemon {
func attack(power: Fire) {
power.blast()
}
}
class Raichu: Pokemon {
func attack(power: Electric) {
power.spark()
}
}
let pikachu = AnyPokemon(Pikachu())
let charmander = AnyPokemon(Charmander())
let raichu = AnyPokemon(Raichu())
pikachu.attack(Electric(charge: 20))
charmander.attack(Fire(level: 10))
let pokemons: [AnyPokemon<Electric>] = [pikachu, raichu]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment