Kleisli在Kotlin求幂

我试图写下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)) } 

只是组成fn次(请不要在我的代码中加n = 0 )。

Kotlin(1.0.6)抱怨error: unsupported [References to variables aren't supported yet]指向::f

我做错了什么?

使用f而不是::f ,它已经是一个函数值(即一个参数 ,一个变量或者一个函数类型的属性),所以你不需要对它做一个可调用的引用。

  ... else { it -> f(kleisli(n - 1, f)(it)) } 

另外,你的例子似乎有一个类型不匹配: kleisli(n - 1, f)返回类型(A) -> B的函数, it的类型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)) } 

(此代码的可运行演示)


而且,这个代码在功能方面表现得非常好,但是可能会导致冗余的对象分配和不希望的调用堆栈增长。 但是,它可以被改写成势在必行的风格,这将更有效地工作:

 fun <T> iterativeKleisli(n: Int, f: (T) -> T) : (T) -> T = { x -> var result = x for (i in 1..n) result = f(result) result }