on Wed Oct 12 2016, Jean-Denis Muys <swift-users-AT-swift.org> wrote:
> Hi, > > I defined this: > > func random(from r: Range<Int>) -> Int { > let from = r.lowerBound > let to = r.upperBound > > let rnd = arc4random_uniform(UInt32(to-from)) > return from + Int(rnd) > } > > so that I can do: > > let testRandomValue = random(from: 4..<8) > > But this will not let me do: > > let otherTestRandomValue = random(from: 4...10) > > The error message is a bit cryptic: > > “No ‘…’ candidate produce the expected contextual result type ‘Range<Int>’” > > What is happening is that 4…10 is not a Range, but a ClosedRange. > > Of course I can overload my function above to add a version that takes a > ClosedRange. > > But this is not very DRY. > > What would be a more idiomatic way? In our original design we had a common protocol to which open and closed ranges conformed, and you could pass an instance of RangeProtocol. That was removed because the overall complexity was not a win, but I predict it will come back for Swift 4: https://github.com/apple/swift/pull/3737 But for what you want to do, you don't need anything that complicated: protocol CompleteRange { associatedtype Bound : Comparable var lowerBound : Bound { get } var upperBound : Bound { get } } extension CountableRange : CompleteRange {} extension CountableClosedRange : CompleteRange {} import Darwin func random<R: CompleteRange>(from r: R) -> Int where R.Bound == Int, R: Collection { let rnd = arc4random_uniform(numericCast(r.count)) return r.lowerBound + Int(rnd) } print(random(from: -5..<5), random(from: -20...20)) Hope this helps, -- -Dave _______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users