Kotlin的Kleisli指数化

时间:2017-04-03 12:00:28

标签: function 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

我做错了吗?

1 个答案:

答案 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

(runnable demo of this code)

此外,此代码在功能样式中完美地展示了这一意图,但它可能导致冗余对象分配和不希望的调用堆栈增长。但是,它可以被重写为命令式风格,这将更有效地工作:

fun <A> kleisli(n: Int, f: (A) -> A) : (A) -> A = 
    if (n == 1) 
        f else 
        { it -> f(kleisli(n - 1, f)(it)) }