Kotlin 高阶函数组合

标签 kotlin

我试图弄清楚如何在 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 来使该操作成为变量。它告诉你的函数如何组合 ab :
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/

相关文章:

android-studio - 创建 Kotlin 类时“期望顶级声明”

android - 如何避免在 Kotlin 中使用 lateinit 字段进行部分覆盖

Android Studio 2.2 找不到所有 kotlin 文件的引用

generics - 在Kotlin中,如何定义具有上限的泛型类型的属性?

android - 即使指定了 "match_parent",使用 ConstraintLayout 的 RecyclerView 项目也不会填满屏幕的整个宽度

serialization - Kotlin 中的单例序列化

android - 为什么使用协程延迟()进行单元测试会失败?

generics - Kotlin - "where"通用约束问题

kotlin - RxKotlin flattenAsObservable() : type mismatch with method reference

generics - 如何在 Kotlin 中编写通用扩展方法?