如何从Arrow kt中的嵌套Eithers中推断错误



我有一些代码如下所示:

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
)
)
}

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

有什么想法可以改变吗?如果这是一个n00b问题,很抱歉,但我仍在努力理解函数式编程和Arrow。

谢谢。

kumbera,

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

您可以通过使用Arrow的计算块来改进这些片段,这些计算块允许以安全的方式从Either中提取值。

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

这里发生的情况是,当您调用bind时,它将返回Either.Right的值,或者它将立即返回either2()作为either.eager的结果返回的Either.Left

还有either计算块的suspend变体,您可以直接用作

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

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

相关内容

  • 没有找到相关文章

最新更新