-
-
Save beccadax/60460ad4578d5d8d52a9d736240cfea6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 | |
/// Returns nil if either parameter is nil, or a tuple of the parameters | |
/// otherwise. | |
func all<T, U>(_ first: T?, _ second: U?) -> (T, U)? { | |
return first.flatMap { first in second.flatMap { second in (first, second) } } | |
} | |
/// Returns a version of the passed two-parameter function which takes a | |
/// tuple of parameters instead. | |
func splatted<T, U, V>(_ function: @escaping (T, U) -> V) -> ((T, U)) -> V { | |
return { tuple in function(tuple.0, tuple.1) } | |
} | |
// 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 all(lhs, rhs).map(splatted(<)) } | |
/// Returns lhs! <= rhs!, otherwise nil | |
public func<=? <T: Comparable>(lhs: T?, rhs: T?) -> Bool? { return all(lhs, rhs).map(splatted(<=)) } | |
/// Returns lhs! == rhs!, otherwise nil | |
public func==? <T: Comparable>(lhs: T?, rhs: T?) -> Bool? { return all(lhs, rhs).map(splatted(==)) } | |
/// Returns lhs! > rhs!, otherwise nil | |
public func>? <T: Comparable>(lhs: T?, rhs: T?) -> Bool? { return all(lhs, rhs).map(splatted(>)) } | |
/// Returns lhs! >= rhs!, otherwise nil | |
public func>=? <T: Comparable>(lhs: T?, rhs: T?) -> Bool? { return all(lhs, rhs).map(splatted(>=)) } | |
// 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