Created
August 7, 2016 16:57
-
-
Save pcantrell/097cb7c08f9da4650c74a702d5f80450 to your computer and use it in GitHub Desktop.
Swift type erasure type puzzler
This file contains 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
import Foundation | |
// ——— The Setup ——— | |
protocol Foo | |
{ | |
associatedtype Bar | |
func modify(bar: Bar) -> Bar | |
} | |
struct Greeter: Foo | |
{ | |
func modify(bar: String) -> String | |
{ return "Hi, \(bar)" } | |
} | |
struct Multiplier: Foo | |
{ | |
var factor: Int | |
func modify(bar: Int) -> Int | |
{ return bar * factor } | |
} | |
struct FooBarPair<F, B where F: Foo, B == F.Bar> | |
{ | |
var foo: F | |
var bar: B | |
func apply() | |
{ print(foo.modify(bar)) } | |
} | |
let a = FooBarPair(foo: Greeter(), bar: "ih") | |
let b = FooBarPair(foo: Multiplier(factor: 6), bar: 7) | |
// ——— The Puzzle ——— | |
// Suppose I have an array of [a,b], and I want to call apply() on every element. | |
// | |
// Note that a caller doesn’t need to know the generic types F, B to call apply(). | |
// If Swift allowed the existential type [FooBarPair], then this would be easy! | |
// But Swift doesn’t, and it isn’t. | |
// | |
// The approach below is the best I’ve found. Is there a simplier way? | |
protocol AnnoyingTypeErasingProtocol | |
{ | |
func apply() | |
} | |
extension FooBarPair: AnnoyingTypeErasingProtocol { } | |
let pairs: [AnnoyingTypeErasingProtocol] = [a,b] | |
for pair in pairs | |
{ pair.apply() } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment