Scheme中可爱的Lambda技巧:在Swift中可能吗?

时间:2018-11-25 21:02:48

标签: swift lambda functional-programming scheme higher-order-functions

很久以前,在一个很远的星系中,在一个Scheme课程中,我们得到了Lambda游戏的示例:

(define (foo x)
  (lambda (y) (x (x (x y)))))

现在,显然((foo 1+) 0)将打印3。(1+是标准的Scheme增量运算符) 但有趣的是,您可以将foo应用于自身,然后可以做一些有趣的事情:

    (((foo foo) 1+) 0)

当然可以打印27。 然后是一个非常有趣的事情:

(define a (foo foo))
(((a foo) 1+) 0)

我在CommonLisp,Clojure,Ruby,Python,Haskell,Erlang和Julia中做了这个技巧。

因此出现了问题,您可以在 Swift 中进行吗? 我知道您可以执行更高阶的函数,但是可以创建像纯函数语言一样“自反”的函数吗?

Tx!

1 个答案:

答案 0 :(得分:2)

如果将foo设为通用,则可以执行以下操作:

func foo<T>(_ x: @escaping (T) -> T) -> (T) -> T {
    return { y in x(x(x(y))) }
}

func inc(x: Int) -> Int {
    return x + 1
}

foo(inc)(0)  // 3
foo(foo)(inc)(0)  // 27

由于foo是通用的,因此当您尝试定义a时,这种情况会下降。

此:

let a = foo(foo)

不编译。

a本身必须是通用的,并且正如注释中提到的@MartinR一样,在Swift中,仅函数可以是通用的。因此a必须定义为一个函数。

这是我的尝试:

func a<T>(_ x: @escaping (T) -> T) -> (T) -> T {
    return foo(foo)(x)
}

a(foo)(inc)(0)  // this runs for quite a long time ...