(I'm not sure if the title describes the problem accurately. Please help me change it if it doesn't.)
I have the following Comparable
extensions:
// Extension 1
extension Comparable where Self: Strideable {
/// Inspects if this value is right next to the given other value.
/// - Parameter other: The given other value.
/// - Returns: `true` if the 2 values are right next to each other, `false` otherwise.
public func borders(on other: Self) -> Bool {
self.separates(from: other, byDegrees: 1)
}
/// Inspects the correctness of the Bacon number between this value and the given other value.
/// - Parameters:
/// - other: The given other value.
/// - degrees: The Bacon number to test for.
/// - Returns: `true` if the Bacon number is correct, `false` otherwise.
public func separates(from other: Self, byDegrees degrees: Self.Stride) -> Bool {
other == self.advanced(by: degrees) || self == other.advanced(by: degrees)
}
}
// Extension 2
extension Comparable {
/// Inspects if the value is right next to the given other value.
/// - Parameter other: The given other value.
/// - Returns: `true` if the 2 values are right next to each other, `false` otherwise.
public func borders(on other: Self) -> Bool {
return false
}
}
The extensions define a new method that checks if 2 values are right next to each other. It works as intended for most of the times:
0.borders(on: 1) // true
1.5.borders(on: 2.3) // false
"a".borders(on: "b") // false
It stops working correctly when the values being compared have the placeholder type within a generic type:
struct Pair<T: Comparable> {
let value1: T
let value2: T
var isAPairOfNeighbours: Bool { value1.borders(on: value2) }
}
let pairOf0And1 = Pair(value1: 0, value2: 1)
type(of: pairOf0And1) // __lldb_expr_30.Pair<Int>.Type
type(of: pairOf0And1.value1) // Int.Type
type(of: pairOf0And1.value2) // Int.Type
pairOf0And1.isAPairOfNeighbours // false, but I expect it to be true
pairOf0And1.value1.borders(on: pairOf0And1.value2) // true
I think the cause of the problem is that within Pair<T>
, the compiler only knows that value1
and value2
are Comparable
, and it doesn't know if they're also Strideable
. Is this true, and is this the correct behaviour? How do I work around this problem?