如何使用Kotlin编写Y组合函数?

如何使用Kotlin编写Y组合函数?,kotlin,y-combinator,Kotlin,Y Combinator,我可以使用Kotlin FP(Lambda,function)编写Y组合函数吗 Y = λf.(λx.f (x x)) (λx.f (x x)) 在JS中: 函数Y(f){ 返回(函数(g){ 返回g(g); })(职能(g){ 返回f(函数(x){ 返回g(g)(x); }); }); } 变量事实=Y(函数(rec){ 返回函数(n){ 返回n==0?1:n*rec(n-1); }; }); 在咖啡中: coffee> Y = (f) -> ((x) -> (x x))

我可以使用Kotlin FP(Lambda,function)编写Y组合函数吗

Y = λf.(λx.f (x x)) (λx.f (x x))
在JS中:

函数Y(f){
返回(函数(g){
返回g(g);
})(职能(g){
返回f(函数(x){
返回g(g)(x);
});
});
}
变量事实=Y(函数(rec){
返回函数(n){
返回n==0?1:n*rec(n-1);
};
});
在咖啡中:

coffee> Y = (f) -> ((x) -> (x x)) ((x) -> (f ((y) -> ((x x) y))))
[Function]

coffee> fact = Y (f)  ->(n) -> if n==0 then 1 else n*f(n-1)
[Function]

coffee> fact(10)
3628800

如何执行此操作?

在Kotlin中,您应该引入一个额外的接口
G
,否则您将得到
取消选中\u CAST
警告,因为Kotlin是一种静态类型的编程语言,而不是动态语言,例如:

typealias X = (Int) -> Int
typealias F = Function1<X, X>
//        v-------------v--- let G reference G recursively
interface G : Function1<G, X>

//  v--- create a G from lazy blocking
fun G(block: (G) -> X) = object : G {
    //                          v--- delegate call `block(g)` like as `g(g)`
    override fun invoke(g: G) = block(g)
}

fun Y(f: F) = (fun(g: G) = g(g))(G { g -> f({ x -> g(g)(x) }) })

val fact = Y({ rec -> { n -> if (n == 0) 1 else n * rec(n - 1) } })
typealias X = (Int) -> Int
typealias F = Function1<X, X>
typealias G = Function1<Any, X>

@Suppress("UNCHECKED_CAST")
//                                           v--- cast `g` to `G`.
fun Y(f: F) = (fun(g: Function1<G, X>) = g(g as G))({ g -> f { x -> g(g)(x) } })

val fact = Y({ rec -> { n -> if (n == 0) 1 else n * rec(n - 1) } })