0

我正在尝试使用 Arrow Either结果而不是 try-catch,但在兔子洞中走得太深了。

我一直在尝试将其Either<Problem,Value>用作我的功能返回类型,Problem就像

sealed interface Problem
data class Caught(val cause: Throwable): Problem
data class DataKeyDisabled(val uuid: UUID, val cause: String): Problem
data class SubscriberNotFound(val uuid: UUID, val cause: String): Problem
data class NotEncrypted(val field: String): Problem

用例的样子

when (val result = transform(...)) {
    is Right -> {}
    is Left -> when (val problem = result.value) {
        is Caught -> {}
        is DataKeyDisabled -> {}
        is SubscriberNotFound -> {}
        is NotEncrypted -> {}
        // else -> {} not needed...
    }
}

但是,确实存在三种类型的问题,我不想一直用尽所有选择。

Problem -> Caught
KeyProblem -> Caught, DataKeyDisabled, SubscriberNotFound
DataProblem -> Caught, DataKeyDisabled, SubscriberNotFound, NotEncrypted

例如,我想要类似的东西

sealed interface Problem
sealed interface KeyProblem : Problem
sealed interface DataProblem : KeyProblem

data class NotHandled(val cause: Throwable): Problem

data class DataKeyDisabled(val uuid: UUID, val cause: String): KeyProblem
data class SubscriberNotFound(val uuid: UUID, val cause: String): KeyProblem

data class NotEncrypted(val cause: String) : DataProblem

我希望能够有一些代码,比如

fun bar(input: Either<Problem,String>) : Either<KeyProblem,String> {

    val something = when (input) {
        is Right -> {}
        is Left  -> {
            when (val problem = input.value) {
                is NotHandled -> {}
                is DataKeyDisabled -> {}
                is SubscriberNotFound -> {}
                is NotEncrypted -> {}
            }
        }

    }
}

但是 Kotlin 抱怨NotHandled,DataKeyDiabled并且SubscriberNotFound不是DataProblem

在某些情况下,我想返回 aKeyProblem以便我可以从 中删除NotEncrypted案例when,而在某些情况下,我只想返回 aProblem这样唯一的案例是NotHandled.

我不知道如何在 Kotlin 中表达这一点。我怀疑不可能在 Kotlin 中表达这一点,所以如果有人告诉我这是不可能的,那就是一个解决方案。

我认为用 Arrow Either 代替 try-catch 是一个错误的决定。如果是这样,请有人告诉我。

我想坚持函数式反应式编程范式,其中 try-catch 不起作用,但使用 Kotlin 协程它确实可以工作。

在我看来,密封的东西的问题是使用时when只能有一层继承,不能再多了?

也许我只是以错误的方式看待整个问题...帮助...请...

4

1 回答 1

1

所以我的解决方案是放弃尝试使用 Arrow Either 和 Kotlin 密封类而不是使用标准

try {
    // return result
}
catch {
    // handle or rethrow
}
finally {
    // clean up
}

虽然多年来我一直在尝试练习响应式和非阻塞式编程,但这在 Scala 中很容易,但在 Kotlin 中并不容易。

在观看了足够多的 Java Project Loom 视频后,我确信这是最好的方法,因为异常处理可以正常工作……我可以使用 Kotlin 协程,因为它们还保留了正确的异常处理,并且可以暂时这样做,但是在从长远来看,虚拟线程和结构化并发是要走的路。

我讨厌使用这些词,但我正在将“范式转变”回归到更清晰的代码,从我陷入的这个兔子洞中撤退。

于 2021-10-22T15:10:19.583 回答