在Swift中,我对定义一个自定义运算符很感兴趣,我可能希望根据上下文改变它的实现。基本上,我想这样做:
infix operator <-> {} // define the operator <->
然后,在我的代码中的某个时刻:
let <-> : (Int, Int) -> Int = (+) // say that here, <-> means +
2 <-> 5 // obtain 7
我仍然希望能够在代码的其他部分中以不同的方式定义<->
(并且可能还有其他参数类型)。而且我不想声明func
,因为指定的函数本身实际上来自外部函数调用。
在Swift 1.2中,这失败了<->
常量定义中的“预期模式”错误。
我做错了什么?有哪些替代方案?
答案 0 :(得分:1)
我能想出的最好的东西是:
infix operator <-> {} // define the operator <->
func <-> (lhs:Int, rhs:Int) -> Int {
return arrowFunction(lhs, rhs)
}
let arrowFunction : (Int, Int) -> Int = (+)
println("\(2 <-> 7)")
答案 1 :(得分:1)
我觉得你试图通过let
绑定试图实现的目标首先不应该起作用(同时与Swift的其余部分保持一致)......我不知道没有足够的PL理论来正确地表达我的观点,但是当您使用let
或var
声明名称时,您需要预先指定类型(并且类型保持固定一次)你已宣布它了,但在这里你不知道实际的类型,直到参数实际通过。
这并不能回答你的问题,但是 - 如果它之后的语法上的甜蜜 - 这里有一些我想出的代码,那么你就可以得到#34; infixify&#34;功能。 (Haven并没有真正测试过它,你可能需要调整优先级和什么不是。它比其他任何东西都更加诙谐。)
func ~<T, U, V>(left: T, f: (T, U) -> V) -> (U -> V) {
return { y in f(left, y) }
}
func ~<U, V>(g: U -> V, right: U) -> V {
return g(right)
}
var plus = {(a: Int, b: Int) in a + b }
2~plus~2 // 4
[1, 2, 3, 4, 5, 7, 8]~contains~{$0 == 6} // false
let dot: ([Double], [Double]) -> Double = { v1, v2 in
return reduce(lazy(Zip2(v1, v2)).map(*), 0, +)
}
func dot: ([Int], [Int]) -> Int {
return 0 // "fake" dot product
}
[1, 2, 3, 4]~dot~[2, 3, 4, 5] // 0
[1.0, 2, 3, 4]~dot~[2, 3, 4, 5] // 40.0