我尝试用 Kotlin 编写 Kleisli 求幂:
fun <A,B> kleisli(n: Int, f: (A) -> B): (A) -> B = if (n == 1) f else { it -> f(kleisli(n-1, ::f)(it)) }
这只是组成 f
, n
次(请不要将 n = 0
放入我的代码中)。
Kotlin (1.0.6) 提示 错误:不支持 [尚不支持对变量的引用]
指向 ::f
。
我做错了什么吗?
最佳答案
仅使用 f
而不是 ::f
,它已经是一个函数值(即参数、变量或属性)函数类型),因此您不需要对其进行可调用引用。
... else { it -> f(kleisli(n - 1, f)(it)) }
此外,您的示例似乎存在类型不匹配:kleisli(n - 1, f)
返回类型为 (A) -> B
的函数,即调用 A
类型的 it
,返回 B
类型的结果。然后将结果传递给f
,但是f
只能接收A
。要解决此问题,您可以删除类型参数 B
并仅保留 A
:
fun <A> kleisli(n: Int, f: (A) -> A) : (A) -> A =
if (n == 1)
f else
{ it -> f(kleisli(n - 1, f)(it)) }
<小时/>
此外,此代码在函数式风格中完美地展示了意图,但它可能会导致冗余对象分配和不期望的调用堆栈增长。但是,它可以重写为命令式样式,这将更有效地工作:
fun <T> iterativeKleisli(n: Int, f: (T) -> T) : (T) -> T = { x ->
var result = x
for (i in 1..n)
result = f(result)
result
}
关于function - Kotlin 中的 Kleisli 求幂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43184115/