-
Notifications
You must be signed in to change notification settings - Fork 233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Type constraints using type equality are unsound #45
Comments
import Foundation
protocol TypeEquality {
typealias From
typealias To
func apply(a: From) -> To
}
struct Refl<X> : TypeEquality {
typealias From = X
typealias To = X
func apply(a: From) -> To {
return a
}
}
struct Tuple2<A, B> {
typealias T = (A, B)
}
extension Array {
func lookup<Key: Equatable, Value, EV: TypeEquality where EV.From == T, EV.To == Tuple2<Key, Value>.T>(ev: EV, key: Key) -> Value? {
return nil
}
}
let xs: Array<Int> = []
let r: String? = xs.lookup(Refl(), key: 1)
// ^ This is impossible, Refl.apply is Int -> String |
There seems to be a much more fundamental problem with this definition beyond the bug in the typechecker: You've essentially defined equality of types struct UtterlyBroken<T> : TypeEquality {
typealias A = T
typealias B = String
func coe(a: A) -> B {
return "Welp";
}
} It is not clear to me that a |
Once we get sealed hierarchies, we'll be able to express it as: @sealed protocol TypeEquality {
typealias A
typealias B
func apply(v : A) -> B
var inverse: TypeEquality<B, A> { get }
}
struct Refl<X>: TypeEquality {
typealias A = X
typealias B = X
func apply(v: X) -> X {
return v
}
var inverse {
return self
}
} I agree with @jonsterling though, and would get rid of this until then. |
Seems to me that a much better solution would be to wait until we've got higher-kinded quantification and then just give leibniz equality... |
Or wait until this works: struct TypeEquality<X, Y> where X: Y && Y: X { ... } I seriously doubt Swift is gaining higher kinds any time soon. :( |
I just confirmed that the following code causes the compiler to segfault: protocol TypeEquality {
typealias A: B
typealias B: A
func apply(v: A) -> B
func unapply(v: B) -> A
}
struct Refl<X>: TypeEquality {
typealias A = X
typealias B = X
func apply(v: X) -> X {
return v
}
func unapply(v: X) -> X {
return v
}
} |
@jonsterling Yup, I agree. I removed it in 4959b4d. One point though, type equality is definitely expressible in swift in a sound way, as a function. Leibniz equality would also be much better. One day... On the representation, I think sealed / closed protocols would stop people from defining their own axioms. |
Is this still an issue in Swift 2? |
Yeah. Terrible, really, that all of this still works. |
The last time I had a crack at this, the problem was if you tried to express something like |
Radar submitted.
Radar: 17377676
With https://github.com/maxpow4h/swiftz/blob/54870ca7b81a2595b3707646cba4d83a71bb6667/swiftz/TypeEquality.swift and https://github.com/maxpow4h/swiftz/blob/54870ca7b81a2595b3707646cba4d83a71bb6667/swiftz/List.swift#L47-L56 you can show
Int =:= String
and define the function:that correctly type checks, showing unsoundness.
Commentary:
It appears swift isn't fully obeying the type constraints provided in where clauses.
The text was updated successfully, but these errors were encountered: