kotlin - 如何在 Arrow-kt 中传播嵌套 Withers 的错误?

标签 kotlin functional-programming arrow-kt

我有一些代码,如下所示:

data class MyStrings(val a: String, val b: String)

sealed class Error {
    object SpecificError0 : Error()
    object SpecificError1 : Error()
    object SpecificError2 : Error()
}

fun either2(): Either<Error, String> =
Either.catch { throw RuntimeException("Either 2") }.mapLeft { Error.SpecificError2 }

fun either4(): Either<Error, MyStrings> =
Either.catch {

    MyStrings(
        a = "Hello",
        b = either2().getOrElse { "" }
    )

}.mapLeft { Error.SpecificError2 }

这将吞掉来自 Either2() 的错误。

如果可能的话,我正在尝试找到一种方法来抛出此错误。

我知道我可以做这样的事情:

fun either5(): Either<Error, MyStrings> =
either2()
    .flatMap {
        Either.Right(
            MyStrings(
                a = "Hello",
                b = it
            )
        )
    }

但是在我需要它之前调用某些东西似乎很奇怪!

关于如何更改任一 4() 有什么想法吗?抱歉,如果这是一个 n00b 问题,但我仍在尝试围绕函数式编程和 Arrow 进行思考。

谢谢。

最佳答案

坎伯拉,

在最后一个片段中,您在需要它之前并没有真正调用它,但从语义上看它确实是这样的。由于 MyStrings 取决于 either2() 的结果,但我们可以用更好的方式重写它,无需嵌套回调即可更好地扩展。

您可以利用 Arrow 的计算 block 来改进这些代码片段,该计算 block 允许以安全的方式从 Either 中提取值。

fun either5(): Either<Error, MyStrings> = either.eager {
  MyStrings(a = "Hello", b = either2().bind())
}

这里发生的情况是,当您调用 bind 时,它要么返回 Either.Right 的值,要么立即返回 Either.Lefteither2() 作为 either.eager 的结果返回。

还有一个either计算 block 的挂起变体,您可以直接将其用作

suspend fun either6(): Either<Error, MyString> = either {
  delay(100)
  MyStrings(a = "Hello", b = either2().bind())
}

我希望完全回答您的问题!

关于kotlin - 如何在 Arrow-kt 中传播嵌套 Withers 的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71002964/

相关文章:

kotlin - 如何制作吞噬异常的函数

functional-programming - 我只是没有继续!

java-8 - 我如何简洁地写一个 || b 其中 a 和 b 是 optional 值?

kotlin - 如何类型安全将 Either 的集合减少到仅 Right

kotlin - 启用 proguard 后无法访问 kotlin 类中使用的伴随对象

kotlin - 我如何在Kotlin中进入0.5楼?

java - 如何在 Kotlin 中使用 Double Epsilon/Precision 调用 assertEquals?

R应用保留属性的功能

arrow-kt - 支持最多具有 22 个构造函数参数的数据类生成 ISO

functional-programming - F# 中是否有类似于 scalaz、cats 和 arrow (Kotlin) 的库?