gpt4 book ai didi

android - 如何在 Kotlin/Arrow.kt 中为生产者 channel 实现 "Railway Pattern"

转载 作者:行者123 更新时间:2023-12-02 10:28:53 26 4
gpt4 key购买 nike

我正在研究当前 Android 应用程序中的 Kotlin 协程和 channel 。

我有以下代码来管理远程 Api 调用并控制 UI 副作用

   private val historical: CompletableDeferred<List<Any>> = CompletableDeferred()
private val mutex = Mutex()

@ExperimentalCoroutinesApi
fun perform(action: Action): ReceiveChannel<List<Any>> =
produce {

mutex.withLock {
if (historical.isCompleted) {
send(historical.getCompleted())
return@produce
}

send(action.sideEffects)
val networkResponse = repository.perform(action)
send(networkResponse.sideEffects)
send(listOf(networkResponse)).also {
historical.complete(listOf(response))
}
}
}

上面的代码给了我想要的结果,但是我想将其重构为类似的东西函数式编程“铁路模式”https://android.jlelse.eu/real-world-functional-programming-with-kotlin-arrow-b5a98e72f5e3

我的流程在哪里

stepOne(Historical.completed)
.stepTwo(action.sideEffects)
.stepThree(getReaction())
.stepFour(reaction.sideEffects)
.finalStep(reaction)

任何步骤失败或历史“isCompleted”时都会“短路”

在 Kotlin 中是否可以实现这种风格的调用?和/或 Kotlin & Arrow.kt?

最佳答案

您可以使用 Arrow-kt 的 Either

您可以使用Either's mapLeft() , map() , flatMap() .

如果结果是 Exception使用mapLeft() 。从 mapLeft() 返回值将是新的Left结果Either ,例如返回是 String ,结果将是 Either<String, List<Any>> 。如果结果是 Right ,即List<Any> , mapLeft()将被跳过,但结果类型无论如何都会发生变化,因此您的类型将是 Either<String, List<Any>>值为Right<List<Any>> 。您也可以返回相同的 Exception来自mapLeft()如果你选择这样

如果您不需要处理特定错误,您可以直接链接 map()flatMap()map()基本上是mapRight()和flatMap()当您想要链式调用时很有用,即链中某处有 List<Any> 的接收者这可能会失败,而您想要处理 ExceptionEither 相同对于该调用,您只需返回 new Either来自flatMap()

代码看起来像这样

fun perform(action: Either<Exception, Action>): ReceiveChannel<List<Any>> =
produce {
// if action is always right, you can start it as Right(action) but then first mapLeft does not make any sense
if (historical.completed) action
.mapLeft {
// handle actions exception here
// transform it to something else or just return it
send(action.sideEffects)
it
}.flatMap {
// handle right side of action either
// assume here that repository may fail and returns Either<Exception, NetworkResponse>
repository.perform(it)
}.mapLeft {
// handle repositorys exception here
// transform it to something else or just return it
send(it)
it
}.map {
// handle network response
send(listOf(networkResponse))
historical.complete(listOf(networkResponse))
}
}

关于android - 如何在 Kotlin/Arrow.kt 中为生产者 channel 实现 "Railway Pattern",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58994937/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com