Last active
August 29, 2015 14:23
-
-
Save allending/c3ccaa994906b8648508 to your computer and use it in GitHub Desktop.
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
//: Playground - noun: a place where people can play | |
import UIKit | |
// - Equatable has a Self requirement, so Value has a Self requirement | |
// - So you couldn't use it as a type anyway: | |
// | |
// e.g. let myValue : Value = ... // doesn't work | |
// | |
// - The problem comes from requiring Value to be Equatable. In this case, | |
// Equatable might not precisely express what the problem author intends. | |
protocol Value: Equatable { | |
} | |
protocol Smashable { | |
func valueBySmashingOtherValue<T: Value>(value: T) -> T | |
} | |
struct Bar : Value { | |
} | |
func ==(lhs: Bar, rhs: Bar) -> Bool { | |
return true; | |
} | |
struct Foo : Value { | |
func valueBySmashingOtherValue<T : Value, R : Value>(value: T) -> R { | |
// - Why as! ? | |
// - Because R has a type constraint of Value, and a Bar is a Value, but | |
// the compiler will not infer that R should be Bar | |
// - That inference happens at the call site below | |
// - But this of course isn't type safe (try replacing smashed: Bar with | |
// smashed: Foo) | |
// - Also, this method is going to be statically dispatched | |
return Bar() as! R; | |
} | |
} | |
func ==(lhs: Foo, rhs: Foo) -> Bool { | |
return true; | |
} | |
let foo = Foo() | |
let smashee = Foo() | |
// - Why Bar type annotation? | |
// - Need Bar so that signature of valueBySmashingOtherValue can be inferred | |
// - Can't use let smashed = foo.valueBySmashingOtherValue(foo) because the | |
// compiler wouldn't know what method to synthesize (R wouldn't be known) | |
// - Can't use let smashed: Value because Value has Self requirement (can't be | |
// used as a type, only a constraint) | |
let smashed: Bar = foo.valueBySmashingOtherValue(smashee) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment