0

在 Swift 中,我有兴趣定义一个自定义运算符,我可能希望根据上下文更改其实现。基本上,我想这样做:

infix operator <-> {} // define the operator <->

然后,在我的代码中的某个时刻:

let <-> : (Int, Int) -> Int = (+)  // say that here, <-> means +
2 <-> 5 // obtain 7

我仍然希望能够<->在代码的其他一些部分中以不同方式定义(并且可能针对其他参数类型)。而且我不想声明funcs,因为分配的函数本身实际上来自外部函数调用。

<->在 Swift 1.2 中,这会失败,并在常量定义中出现错误“预期模式” 。

我究竟做错了什么?有哪些替代方案?

4

2 回答 2

1

我能想到的最好的方法是:

infix operator <-> {} // define the operator <->

func <-> (lhs:Int, rhs:Int) -> Int {
    return arrowFunction(lhs, rhs)
}

let arrowFunction : (Int, Int) -> Int = (+)

println("\(2 <-> 7)")
于 2015-02-10T17:31:19.493 回答
1

我觉得首先不应该期望您通过绑定尝试实现的目标let(同时与 Swift 的其余部分保持一致)......我不知道足够的 PL 理论来正确表达我的观点,但是,当您使用letor声明名称时var,您会事先指定类型(并且一旦您声明了类型,它就会保持固定),但是在实际传递参数之前,您不知道实际的类型。

这并不能回答你的问题,但是 - 如果它是你所追求的语法甜味 - 这是我想出的一些代码,可以让你“中缀”函数。(虽然还没有真正测试过,你可能需要调整优先级和其他什么。它比其他任何东西都更半开玩笑。)

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
于 2015-02-10T18:55:56.420 回答