首页 文章

Kotlin撰写功能列表

提问于
浏览
0

目前我使用的是一个名为arrow的库,它以这种方式定义 .

inline infix fun <IP, R, P1> ((IP) -> R).compose(crossinline f: (P1) -> IP): (P1) -> R = { p1: P1 -> this(f(p1)) }

我想要做的是从列表中编写函数,所以我假设一些简单的东西可以工作 .

val add5 = { i: Int -> Option(i + 5) }
val multiplyBy2 = { i: Int -> i * 2 }
fun isOdd(x: Option<Int>) = x.map { y -> y % 2 != 0 }

val composed = listOf(::isOdd, add5, multiplyBy2).reduce { a, b -> a compose b  }

但我得到类型错误:

类型推断失败:无法推断内联中缀乐趣中的类型参数IP((IP) - > R) . 撰写(crossinline f:(P1) - > IP):( P1) - > R以下替换接收者:任何) - >任何参数:((没什么) - >任何)接收者:(没什么) - >任何参数:((Nothing) - > Nothing)可以应用于接收者:Function1 <,Any>参数:(Function1 <,任何>)

所以我尝试:

val composed = listOf<(Any) -> Any>(::isOdd, add5, multiplyBy2).reduce { x, y -> x compose y }

我明白了

类型不匹配:推断类型是KFunction1 <@ParameterName选项,选项>但是(任意) - >任何预期类型不匹配:推断类型是(Int) - >选项但是(任何) - >任何预期类型不匹配:推断类型是(Int) - > Int但是(任何) - >任何预期

任何帮助赞赏 . 我不介意我是否最终必须编写自己的撰写版本 . 我只需要能够编写一个函数列表 .

编辑:

这没有问题:

val composed = ::isOdd compose add5 compose multiplyBy2

我只是想尝试获得相同的结果,如果我有一个函数列表而不是这样写 .

1 回答

  • 1

    我发现很难想象一个简单的组合应该如何处理具有如此不同签名的方法 . 首先,我们必须调整函数的类型 . 如果第一个的返回类型与第二个参数匹配,那么让你编写函数...

    另一个问题是 isOddPredicate . 它没有改变 Value .

    如果变压器具有兼容的签名,您可以使用例如 andThen

    这是一个对齐类型以组成函数的版本 . 注意 filtermap 是箭头 Option 中的特殊函数,允许您传递变换函数/谓词

    import arrow.core.Option
    import arrow.core.andThen
    import org.hamcrest.Matchers.`is`
    import org.junit.Assert.assertThat
    import org.junit.Test
    
    class ComposeTest {
    
        @Test
        fun shouldCompose() {
            val add5 = { i: Int -> i + 5 }
            val multiplyBy2 = { i: Int -> i * 2 }
            val isOdd = { x: Int -> x % 2 != 0 }
    
            val composed: (Int) -> Option<Int> = { i: Int -> Option.just(i)
              .filter(isOdd)
              .map(add5.andThen(multiplyBy2))
            }
    
            assertThat(composed(3), `is`(Option.just(16)))
            assertThat(composed(4), `is`(Option.empty()))
        }
    }
    

相关问题