【问题标题】:Does Kotlin support partial application?Kotlin 是否支持部分应用程序?
【发布时间】:2018-10-09 00:06:58
【问题描述】:

由于 Kotlin 支持函数式编程的许多概念,我想知道是否有办法在 Kotlin 中也对函数进行部分应用?

部分应用可能有用的一个例子是:

// In one class
fun doSomething(cb: (a, b) -> Unit) {
    <some logic here to compute someField>
    doSomethingElse(cb.applyPartially(someField))
}

// In another class
fun doSomethingElse(cb: (b) -> Unit) {
    <some logic here to compute someOtherField>
    cb(someOtherField)
}

【问题讨论】:

    标签: kotlin functional-programming partial-application


    【解决方案1】:

    开箱即用,不。但是使用辅助函数并不难:

        fun add(a: Int, b:Int): Int {
            return a + b
        }
    
        fun <A, B, C> partial2(f: (A, B) -> C, a: A): (B) -> C {
            return { b: B -> f(a, b)}
        }
    
        val add1 = partial2(::add, 1)
    
        val result = add1(2) //3
    

    所以 partial2 接受一个有 2 个参数的函数和第一个参数,并将它应用到一个有 1 个参数的函数。你必须为你需要的所有 arities 编写这样的助手。

    或者,您可以使用扩展方法来做到这一点:

    fun <A,B,C> Function2<A,B,C>.partial(a: A): (B) -> C {
        return {b -> invoke(a, b)}
    }
    
    val abc: (Int) -> Int = (::add).partial(1)
    

    【讨论】:

    • 现在我需要的只是一种向函数添加扩展函数的方法。
    • 是的,我能够做到这一点。现在的问题是这仅适用于具有 2 个参数的函数。我现在正在尝试为 n 个参数函数设计一个解决方案。
    • 我编写了一个 JavaScript 脚本来生成这些函数,最多可以使用 20 个参数 LOL:gist.github.com/idunnololz/56ffb520c164bef13766dc0fb551ee0d
    • 不是 lambda,例如doSomethingElse{ cb(someField, it) },一个更简单的解决方案? (免责声明:我不是 FP 开发人员……)
    • 严格来说不一样,但也可以更直接的定义。 val abc = {b:Int -&gt; add(1, b) }。成为特定于每种用法的约定,首先部分应用的约定,并且必须明确定义参数的类型。风格选择。
    【解决方案2】:

    Kotlin 有一个非常漂亮和轻量级的库:org.funktionale。在模块 funktionale-currying 中,您会找到 lambdas 的扩展方法:curried()uncurried()

    例子:

    val add = { x: Int, y: Int -> x + y }.curried()
    val add3 = add(3)
    
    fun test() {
        println(add3(5)) // prints 8
    }
    

    【讨论】:

    • 小更新:项目好像已经迁移到:arrow-kt.io
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多