如何使用 Kotlin 编写 Y 组合函数?
How to use Kotlin to Write a Y-combinator function?
我可以使用 Kotlin FP (Lambda, function) 编写 Y 组合器函数吗?
Y = λf.(λx.f (x x)) (λx.f (x x))
在 JS 中:
function Y(f) {
return (function (g) {
return g(g);
})(function (g) {
return f(function (x) {
return g(g)(x);
});
});
}
var fact = Y(function (rec) {
return function (n) {
return 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
,否则您将收到 UNCHECKED_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) } })
另一个版本将 Function1<G, X>
转换为 G
,因此它应该抑制 UNCHECKED_CAST 警告,例如:
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) } })
我可以使用 Kotlin FP (Lambda, function) 编写 Y 组合器函数吗?
Y = λf.(λx.f (x x)) (λx.f (x x))
在 JS 中:
function Y(f) {
return (function (g) {
return g(g);
})(function (g) {
return f(function (x) {
return g(g)(x);
});
});
}
var fact = Y(function (rec) {
return function (n) {
return 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
,否则您将收到 UNCHECKED_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) } })
另一个版本将 Function1<G, X>
转换为 G
,因此它应该抑制 UNCHECKED_CAST 警告,例如:
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) } })