Try to think in terms of abstract collections and implement your algorithms that way. In the generic setting, the difference between Index and IndexDistance is enforced by the type checker:
extension Collection {
var middleElement: Element {
let middleIndex = self.index(self.startIndex, offsetBy: self.count / 2)
return self[middleIndex]
}
}
print((4 ..< 8).middleElement) // 6