I know how to customize binary operators, like this
infix operator ** { associativity left precedence 170 }
func ** (left: Double, right: Double) -> Doubl
You can actually do this by declaring two separate operators that work together and using a curried function for one of the operators.
Let's declare a ternary operator x +- y +|- z that will check the sign of the initial value x, and then return the second value y if the sign is zero or positive and the final value z if the sign is negative. That is, we should be able to write:
let sign = -5 +- "non-negative" +|- "negative"
// sign is now "negative"
We'll start by declaring the two operators. The important part is to have higher precedence on the second operator - we'll evaluate that part first and return a function:
infix operator +- { precedence 60 }
infix operator +|- { precedence 70 }
Then define the functions - we'll define the second first:
func +|-(lhs: @autoclosure () -> T, rhs: @autoclosure () -> T)(left: Bool) -> T {
return left ? lhs() : rhs()
}
The important part here is that this function is curried -- if you only call it with the first two parameters, instead of returning a T value, it returns a (left: Bool) -> T function. That becomes the second parameter of the function for our first operator:
func +-(lhs: I, rhs: (left: Bool) -> T) -> T {
return rhs(left: lhs >= 0)
}
And now we can use our "ternary" operator, like this:
for i in -1...1 {
let sign = i +- "" +|- "-"
println("\(i): '\(sign)'")
}
// -1: '-'
// 0: ''
// 1: ''
Note: I wrote a blog post on this subject with another example.