Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
// One note before we start: if the inhabitants of Value are a closed set,
// then making Value an enum is going to be a clearer model than using a
// protocol like this. I'm assuming you need to be able to retroactively add
// new members of Value.
// Can't use Equatable directly because of its Self requirement.
protocol HeteroEquatable {
func isEqualTo(value: HeteroEquatable) -> Bool
}
func ==(lhs: HeteroEquatable, rhs: HeteroEquatable) -> Bool {
return lhs.isEqualTo(rhs)
}
protocol Value: HeteroEquatable {}
protocol Smashable {
func valueBySmashingOtherValue(value: Value) -> Value
}
extension Int: Value {
func isEqualTo(a: HeteroEquatable) -> Bool {
if let a = a as? Int {
return self == a
} else {
return false
}
}
}
struct Test {
func valueBySmashingOtherValue(value: Value) -> Value {
return 0 // This is free to return a different adopter of Value
}
}
let result = Test().valueBySmashingOtherValue(3)
println(result == 3) // can still ==
@andymatuschak
Owner

Yeah, sorry, fixed.

@Inferis
Inferis commented Jun 21, 2015

But that doesn't work with Brent's example: Bar() is not convertible to U.
Which makes sense, since U is defined by the caller of the function and not the function itself. So returning Bar here isn't valid.

(accidentally deleted comment /o)

@andymatuschak
Owner

Oops, no, it's not fixed yet…

@Inferis
Inferis commented Jun 21, 2015

No, you can't do it currently AFAIK. Not without getting rid of the Self requirement of Equatable.

@andymatuschak
Owner

Okay. No. I don't think it's fixable in Swift currently.

Per @jckarter, Value can't be both Equatable and used as a dynamic type because Equatable requires a Self constraint, but the result of valueBySmashingOtherValue would be type-erased, so you couldn't actually use it as an equatable…

You could get around this by making Value heterogeneously equatable.

@andymatuschak
Owner

(updated to a version with Value heterogeneously equatable)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment