【问题标题】:Kotlin - Composition of multiples IOKotlin - 倍数 IO 的组合
【发布时间】:2020-08-16 04:40:17
【问题描述】:

我是 Kotlin 的 Arrow 框架的新手,我有几个问题:

假设

fun getUser(id: Int): IO<Option<User>>
fun getCards(user: User): IO<List<Card>>


fun getUserAndCards(id: Int): IO<Option<Pair<User, List<Card>>>> = IO.fx {
    when (val user = !userRepository.get(id)) {
        is None -> None
        is Some -> {
            val cards = !cardRepository.get(user.t.id)
            Some(Pair(user.t, cards))
        }
    }
}

如何以“箭头时尚”的方式实现相同的功能?

我设法得到:

fun getUserAndCards(id: Int): IO<Option<Pair<User, List<Card>>>> = IO.fx {
    userRepository.get(id).bind().map { user ->
        val cards = cardRepository.get(user.id).bind()
        Pair(user, cards)
    }
}

但我在第二个bind() 中获得Suspension functions can be called only within coroutine body

编辑: 我看到this post 有同样的问题。在提供的答案中,它说 问题是未涵盖 left/none 选项。 但它已涵盖,当将 map 应用于 None 时,预计会获得 @ 987654328@.

【问题讨论】:

    标签: kotlin concurrency functional-programming arrow-kt


    【解决方案1】:

    随着新的 0.11.0 版本即将发布,最惯用的方法是使用 Arrow Fx Coroutines。

    将示例重写为 Arrow Fx Coroutines 将是:

    suspend fun getUser(id: Int): Option<User>
    suspend fun getCards(user: User): List<Card>
    
    
    suspend fun getUserAndCards(id: Int): Option<Pair<User, List<Card>>> =
      option {
        val user = !userRepository.get(id)
        val cards = !cardRepository.get(user.t.id)
        Pair(user.t, cards)
      }
    

    您现在可以依靠option { } DSL 从Option 中提取值。

    问题是未涵盖 left/none 选项。但是它被覆盖了,当将 map 应用于 None 时,预计会获得 None。

    你说得对,它被覆盖了,但是! 是一个挂起函数,map 目前没有内联,所以你不能在里面调用!。在 0.11.0 版本中,Arrow-Core 中数据类型的运算符是 inline,以改进对 suspend 函数的支持,这将解决 Suspension functions can be called only within coroutine body 错误。

    在其他函数式语言中,例如 Haskell monad 转换器经常使用 (OptionT),但在 Kotlin 中使用 suspend 更合适,它与包装 monad 转换器相比也具有相当多的性能优势。

    正如另一篇文章中提到的,您也可以随时使用traversesequence 来翻转两个容器。 Option&lt;IO&lt;User&gt;&gt; -&gt; IO&lt;Option&lt;User&gt;&gt;

    【讨论】:

    • 期待 Arrow 0.11 :)
    猜你喜欢
    • 1970-01-01
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多