Kleisli幂在科特林
问题描述:
我试着写了Kleisli幂在科特林: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
。
我做错了什么?
答
使用的只是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
}
谢谢!这样可行。似乎我需要更多地了解Kotlin。也很抱歉错过了构成f,f需要是 - > a。 –
只是为了好奇,那个错误是什么意思(引用变量还不支持)? –
@Koyomi-chan,如果支持,':: f'将意味着对函数参数'f'的可调用引用 - 一个包含有关该参数的一些信息并提供获取其值的方法的对象。已经有[函数引用](http://kotlinlang.org/docs/reference/reflection.html#function-references)和[绑定可调用引用](https://gist.github.com/udalov/f86fbea722a53730f3f5777d871ab8ba) Kotlin,都使用'::'。但现在不支持局部变量和参数引用。 – hotkey