我试图弄清楚如何在 Kotlin 中将一个函数声明性地定义为其他两个函数的组合,但我很挣扎。这是我的代码:
fun compose(a: (Int, Int) -> Int, b: (Int, Int) -> Int): Int {
return a.invoke() + b.invoke()
}
compose 函数的想法是,它将接受两个函数作为输入(这两个函数都接受两个 Int 并返回一个 Int)并返回两个传递函数的结果之和。问题是我必须调用传递的函数来计算它们的总和(显然大声笑)但我不知道我希望在 compose 方法内部调用的值(它们是传递给函数的值)。
我在这里完全错过了什么吗?我知道这在像 Haskell 这样的语言中是可能的,在 Kotlin 中是否可能?
最佳答案
一种方式:
您必须将两个 Int 作为附加参数传递给 compose
像这样:
fun compose(
c: Int, d: Int, a: (Int, Int) -> Int, b: (Int, Int) -> Int
) = a(c, d) + b(c, d)
Lambda 是更深层次的抽象,它让您有机会使行为可变,但您仍然必须为它们提供数据。更抽象的方法:
你可以进一步抽象,让
compose
返回一个 lambda,它结合了其他两个 lambda 的结果(我们称之为 compose2
):// return type is inferred to (Int, Int) -> Int
fun compose2(a: (Int, Int) -> Int, b: (Int, Int) -> Int) = {
c: Int, d: Int -> a(c, d) + b(c, d)
}
val f = compose2(/* pass lambdas */)
f
是一个 lambda 本身,可以这样调用:f(2, 4)
所以,compose2
只返回一个 lambda,它将两个传递的 lambda 的结果相加。实际调用是在 compose2
之外完成的.更抽象的方法:
在您的 compose 函数中,您使用简单的加法作为组合操作。您甚至可以通过传递第三个 lambda
ab
来使该操作成为变量。它告诉你的函数如何组合 a
和 b
:fun compose3(
a: (Int, Int) -> Int, b: (Int, Int) -> Int, ab: (Int, Int) -> Int
) = {
c: Int, d: Int -> ab(a(c, d), b(c, d))
}
结果再次是一个 lambda,它接受两个 Int 并返回一个 Int。
关于Kotlin 高阶函数组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48932504/