我正在试验一阶谓词微积分的闭合用法,并且我打算定义以下功能:
func ASSUM<U, V>(p: @escaping Pred<U>) -> (Pred<U>) -> Pred<(U, V)> {
return { q in AND1(p: p, q: q) }
}
以参数为谓词 p: Pred<U>
,其中 Pred<U>
是 (T) -> Bool
的typealias:
typealias Pred<T> = (T) -> Bool
ASSUM
的返回是类型(Pred<U>)->Pred<(U,V)>
的谓词变压器闭合。
但是,编译器返回以下错误:
Passing non-escaping parameter 'q' to function expecting an @escaping closure
我了解函数AND1
作为定义请求逃脱参数:
func AND1<U, V>(p: @escaping Pred<U>, q: @escaping Pred<V>) -> Pred<(U, V)> {
return { (x, y) in (p(x) && q(y)) }
}
,但我没有成功地在{ q in AND1(p: p, q: q) }
逃脱中明确制作q
。
我该如何修复?
您必须将@escaping
属性添加到ASSUM
的返回类型闭合的参数:
typealias Pred<T> = (T)->Bool
func AND1<U, V>(p: @escaping Pred<U> , q: @escaping Pred<V>) -> Pred<(U, V)> {
return { (x,y) in (p(x) && q(y)) }
}
func ASSUM<U, V>(p: @escaping Pred<U>) -> (@escaping Pred<V>) -> Pred<(U, V)> {
/* ^ note: I believe you
want V here, not U */
return { AND1(p: p, q: $0) }
}
在返回的闭合中,q
(匿名$0
参数)正确地推断为@escaping
(并且不需要明确标记为@hamish指出,谢谢!)。
还要注意,ASSUM
中的通用类型V
必须通过呼叫者通过显式类型注释(或转换)来推断,因为它不包含在ASSUM
的任何参数中。
/* example usage */
let foo = { $0 < 2 }
let bar = { $0 != "bar" }
let fooAnd: (@escaping Pred<String>) -> Pred<(Int, String)> = ASSUM(p: foo)
let fooAndBar = fooAnd(bar)
print(fooAndBar((1, "foo"))) // true
print(fooAndBar((1, "bar"))) // false
print(fooAndBar((2, "foo"))) // false
最后,ALLCAPITAL
函数名称与Swift命名约定不符:您应该更喜欢camelCase
命名(例如,请参见Swift API指南有关的其他详细信息)。