在swift中,是否可以让一个函数接受与其自身相同类型的另一个函数?
例如,我在python中有这个函数:
lambda f: f(f)
如何在swift中定义这样的函数? f的类型是什么?
答案 0 :(得分:3)
从您的问题来看,听起来好像您正在寻找定义self-application combinator (/U combinator)的方法。我不确定它是否可以在Swift中实现U组合器行为,但是你可以深入到相关的fix-point combinator (/Y combinator)和递归闭包中。
您可以通过定义一个函数来实现Y组合器的行为,该函数将函数用作参数的高阶函数,比如f: (T->U) -> (T->U)
,并返回相同的类型功能,即(T->U)
。使用这种方法,您的函数可以将诸如 result from 本身的函数作为参数。
简短版本是Y组合子计算的固定点 功能性 - 消耗(在这种情况下,产生)的功能 另一个功能。
诀窍是将递归函数定义为固定点 非递归函数,然后写一个定点查找器 - Y组合子 - 不使用递归。
来自http://matt.might.net/articles/js-church/。
现在,由于您返回一个函数,您的返回将是"嵌套"分两步;外部定义了闭包的返回,而内部则返回了类型。关键是内在的,递归的,回归;你在没有明确使用它的名字的情况下调用输入(参数)函数本身:你使用函数参数---如上所述---构造为一个可以保存函数本身的闭包类型。
func myCombinator<T,U>(f: (T->U) -> (T->U)) -> (T->U) {
return {
(x: T) -> U in
return f(myCombinator(f))(x)
}
}
使用此功能,您可以,例如,计算数字的阶乘,而不使用明确引用其自身名称的函数
func factorialHelper(recursion: Int -> Int)(n: Int) -> Int {
switch n {
case 0: return 1
default: return n * recursion(n-1)
}
}
let factorial = myCombinator(factorialHelper)
print("\(factorial(4))") // 24
有关Y组合子和Swift上下文中的递归闭包的参考,请参阅例如。
这是上面的第二个参考,本答案中的例子就是这样做的。
很快回到U组合,有一个简单的&#34;本地&#34;快速案例(但是,相当无用),至少模拟lambda f: f(f)
形式。
考虑一个void函数,比如f
,将空元组 type 作为单个函数参数。空元组()
是一种类型(typealias Void
引用类型()
)以及该类型的单个值。由于f
为void(无显式返回),因此它隐式返回空元组()
作为值。
因此---虽然与U组合器没有真正关系 - 你可以写一些类似
的东西func f(_: ()) { }
var lambda_f = f(f())
lambda_f = f(f(f()))