如何在 swift 中编写 not/negate 高阶函数?
How do I write the not/negate higher order function in swift?
我是一名 Javascript 开发者,我喜欢使用 not/negate
函数:
function not (predicateFunc) {
return function () {
return !predicateFunc.apply(this, arguments);
};
}
我正在尝试对 swift 做同样的事情:
func not <A> (_ f: @escaping (_ A: Any) -> Bool) -> (A) -> Bool {
return { a in !f(a) }
}
但我收到类似
的错误
generic parameter 'T' could not be inferred
和
Cannot convert value of type '(_) -> Bool' to expected argument type '(Any) -> Bool'
我正在寻找的结果是当我有这样的函数时:
func isEmpty<T: Collection>(collection: T) -> Bool {
return collection.count == 0
}
我可以像这样创建一个 notEmpty
函数:
let notEmpty = not(isEmpty)
然后像
一样使用它
notEmpty([3,4,5]) // true
我做错了什么?
使用Any
是一种代码味道。你可以直接扩展 Collection:
extension Collection {
var notEmpty: Bool {
return !isEmpty
}
}
[1, 3, 5].notEmpty // true
您对 not
的函数定义可以这样工作:
func not <A> (_ f: @escaping (_ a: A) -> Bool) -> (A) -> Bool {
return { a in !f(a) }
}
但是要调用它,您需要这样的东西:
let arrayNotEmpty = not { (array: [Int]) in array.isEmpty }
arrayNotEmpty([1, 3, 5]) // true
你有两个错误:
- 您正在使用
A
作为类型参数和参数名称。
- 您正在使用
Any
作为参数类型,而不是使用类型参数 (A
) 作为参数类型。
试试这个:
func not<A>(predicate: @escaping (A) -> Bool) -> (A) -> Bool {
return { !predicate([=10=]) }
}
请注意,在此版本中,我没有为谓词参数使用参数名称。您不需要在声明中使用参数名称 ((A) -> Bool
),我在正文中使用匿名参数名称 ([=18=]
)。
好的,所以你要写这个:
func isEmpty<T: Collection>(collection: T) -> Bool {
return collection.count == 0
}
func not<A>(_ predicate: @escaping (A) -> Bool) -> (A) -> Bool {
return { !predicate([=11=]) }
}
let notEmpty = not(isEmpty)
你得到这个错误:
let notEmpty = not(isEmpty)
^ Generic parameter 'A' could not be inferred
问题是此代码试图创建通用闭包,但 Swift 不支持通用闭包。
也就是说,nonEmpty
的类型是什么?它会是这样的:
<A: Collection>(A) -> Bool
和Swift不支持。
我是一名 Javascript 开发者,我喜欢使用 not/negate
函数:
function not (predicateFunc) {
return function () {
return !predicateFunc.apply(this, arguments);
};
}
我正在尝试对 swift 做同样的事情:
func not <A> (_ f: @escaping (_ A: Any) -> Bool) -> (A) -> Bool {
return { a in !f(a) }
}
但我收到类似
的错误generic parameter 'T' could not be inferred
和
Cannot convert value of type '(_) -> Bool' to expected argument type '(Any) -> Bool'
我正在寻找的结果是当我有这样的函数时:
func isEmpty<T: Collection>(collection: T) -> Bool {
return collection.count == 0
}
我可以像这样创建一个 notEmpty
函数:
let notEmpty = not(isEmpty)
然后像
一样使用它 notEmpty([3,4,5]) // true
我做错了什么?
使用Any
是一种代码味道。你可以直接扩展 Collection:
extension Collection {
var notEmpty: Bool {
return !isEmpty
}
}
[1, 3, 5].notEmpty // true
您对 not
的函数定义可以这样工作:
func not <A> (_ f: @escaping (_ a: A) -> Bool) -> (A) -> Bool {
return { a in !f(a) }
}
但是要调用它,您需要这样的东西:
let arrayNotEmpty = not { (array: [Int]) in array.isEmpty }
arrayNotEmpty([1, 3, 5]) // true
你有两个错误:
- 您正在使用
A
作为类型参数和参数名称。 - 您正在使用
Any
作为参数类型,而不是使用类型参数 (A
) 作为参数类型。
试试这个:
func not<A>(predicate: @escaping (A) -> Bool) -> (A) -> Bool {
return { !predicate([=10=]) }
}
请注意,在此版本中,我没有为谓词参数使用参数名称。您不需要在声明中使用参数名称 ((A) -> Bool
),我在正文中使用匿名参数名称 ([=18=]
)。
好的,所以你要写这个:
func isEmpty<T: Collection>(collection: T) -> Bool {
return collection.count == 0
}
func not<A>(_ predicate: @escaping (A) -> Bool) -> (A) -> Bool {
return { !predicate([=11=]) }
}
let notEmpty = not(isEmpty)
你得到这个错误:
let notEmpty = not(isEmpty)
^ Generic parameter 'A' could not be inferred
问题是此代码试图创建通用闭包,但 Swift 不支持通用闭包。
也就是说,nonEmpty
的类型是什么?它会是这样的:
<A: Collection>(A) -> Bool
和Swift不支持。