Skip to content

Instantly share code, notes, and snippets.

@allending
Last active August 29, 2015 14:23
Show Gist options
  • Save allending/c3ccaa994906b8648508 to your computer and use it in GitHub Desktop.
Save allending/c3ccaa994906b8648508 to your computer and use it in GitHub Desktop.
//: 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