Skip to content

Instantly share code, notes, and snippets.

@erica
Last active August 3, 2017 15:36
Show Gist options
  • Save erica/77b110e17e51dbea7d6934e6582f627f to your computer and use it in GitHub Desktop.
Save erica/77b110e17e51dbea7d6934e6582f627f to your computer and use it in GitHub Desktop.
// Evaluates the given closure when two `Optional` instances are not `nil`,
// passing the unwrapped values as parameters. (Thanks, Mike Ash, Tim Vermeulen)
// Following the example of IEEE754 with NAN, any comparison involving
// .None is false
//
// See also: http://stackoverflow.com/questions/1565164/what-is-the-rationale-for-all-comparisons-returning-false-for-ieee754-nan-values
// Brent RG has a really interesting take here: https://gist.github.com/brentdax/60460ad4578d5d8d52a9d736240cfea6
fileprivate func _flatMap2<T, U, V>(_ first: T?, _ second: U?, _ transform: (T, U) throws -> V?) rethrows -> V? {
return try first.flatMap({ first in
try second.flatMap({ second in
try transform(first, second) })})
}
// MARK: Failable Optional Comparisons
precedencegroup OptionalComparisonPrecedence {
higherThan: NilCoalescingPrecedence
}
infix operator <?: OptionalComparisonPrecedence
infix operator <=?: OptionalComparisonPrecedence
infix operator ==?: OptionalComparisonPrecedence
infix operator >?: OptionalComparisonPrecedence
infix operator >=?: OptionalComparisonPrecedence
/// Returns lhs! < rhs!, otherwise nil
public func<? <T: Comparable>(lhs: T?, rhs: T?) -> Bool? { return _flatMap2(lhs, rhs, <) }
/// Returns lhs! <= rhs!, otherwise nil
public func<=? <T: Comparable>(lhs: T?, rhs: T?) -> Bool? { return _flatMap2(lhs, rhs, <=) }
/// Returns lhs! == rhs!, otherwise nil
public func==? <T: Comparable>(lhs: T?, rhs: T?) -> Bool? { return _flatMap2(lhs, rhs, ==) }
/// Returns lhs! > rhs!, otherwise nil
public func>? <T: Comparable>(lhs: T?, rhs: T?) -> Bool? { return _flatMap2(lhs, rhs, >) }
/// Returns lhs! >= rhs!, otherwise nil
public func>=? <T: Comparable>(lhs: T?, rhs: T?) -> Bool? { return _flatMap2(lhs, rhs, >=) }
// MARK: Unwrapped Optional Comparisons
/// Returns lhs! < rhs!, otherwise false
public func< <T: Comparable>(lhs: T?, rhs: T?) -> Bool { return lhs <? rhs ?? false }
/// Returns lhs! <= rhs!, otherwise false
public func<= <T: Comparable>(lhs: T?, rhs: T?) -> Bool { return lhs <=? rhs ?? false }
/// Returns lhs! == rhs!, otherwise false
public func== <T: Comparable>(lhs: T?, rhs: T?) -> Bool { return lhs ==? rhs ?? false }
/// Returns lhs! > rhs!, otherwise false
public func> <T: Comparable>(lhs: T?, rhs: T?) -> Bool { return lhs >? rhs ?? false }
/// Returns lhs! >= rhs!, otherwise false
public func>= <T: Comparable>(lhs: T?, rhs: T?) -> Bool { return lhs >=? rhs ?? false }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment