我怎么能有一个函数接受一个相同类型的函数?

时间:2016-01-02 08:03:30

标签: swift

在swift中,是否可以让一个函数接受与其自身相同类型的另一个函数?

例如,我在python中有这个函数: lambda f: f(f)

如何在swift中定义这样的函数? f的类型是什么?

1 个答案:

答案 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()))