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

How to propage errors from nested Eithers in 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() 的错误。

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

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

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

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

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

谢谢。

昆贝拉,

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

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

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

这里发生的是,当你调用 bind 时,它要么 return Either.Right 的值,要么立即 return Either.Left return由 either2() 编辑作为 either.eager 的结果。

either 计算块还有一个 suspend 变体,您可以直接将其用作

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

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