Skip to content

Instantly share code, notes, and snippets.

@haranicle
Created November 30, 2016 16:48
Show Gist options
  • Save haranicle/5a22d4b4d08c07945e4c095117952f9c to your computer and use it in GitHub Desktop.
Save haranicle/5a22d4b4d08c07945e4c095117952f9c to your computer and use it in GitHub Desktop.
import Foundation
class Thunder { }
class Fire { }
protocol Pokemon {
associatedtype PokemonType
func attack(move:PokemonType)
}
struct Pikachu: Pokemon {
typealias PokemonType = Thunder
func attack(move: Thunder) { /*⚡️*/ }
}
class Charmander: Pokemon {
func attack(move: Fire) { /*🔥*/ }
}
class Raichu: Pokemon {
typealias PokemonType = Thunder
func attack(move: Thunder) { /*⚡️*/ }
}
class AnyPokemon <V>: Pokemon {
typealias PokemonType = V
private let _attack: ((PokemonType) -> Void)
required init<U:Pokemon>(_ pokemon: U) where U.PokemonType == PokemonType {
_attack = pokemon.attack
}
func attack(move type:PokemonType) {
return _attack(type)
}
}
let thunderAttack = Thunder()
let fireAttack = Fire()
let pikachu: AnyPokemon<Thunder>
pikachu = AnyPokemon(Pikachu())
pikachu.attack(move: thunderAttack)
let raichu: AnyPokemon<Thunder>
raichu = AnyPokemon(Raichu())
raichu.attack(move: thunderAttack)
let electricPokemon = [pikachu, raichu]
for pokemon in electricPokemon {
pokemon.attack(move: thunderAttack)
}
let charmander: AnyPokemon<Fire>
charmander = AnyPokemon(Charmander())
charmander.attack(move: fireAttack)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment