我试着在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)抱怨error: unsupported [References to variables aren't supported yet]
指向::f
。
我做错了吗?
答案 0 :(得分:3)
仅使用f
代替::f
,它已经是一个功能值(即参数,变量或功能类型的属性),所以你不要不需要对它进行可调用的引用。
... else { it -> f(kleisli(n - 1, f)(it)) }
此外,您的示例似乎存在类型不匹配:kleisli(n - 1, f)
返回类型(A) -> B
的函数,该函数在类型it
的{{1}}上调用,返回结果类型为A
。然后结果传递给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)) }