自动表达时的kotlin

时间:2019-02-14 15:42:08

标签: kotlin arrow-kt

我希望以下kotlin代码能够正常工作:

val result: Try<Option<String>> = Success(Some("test"))

val test = when {
    result is Success && result.value is Some -> result.value.t // not working
    result is Success && result.value is None -> "Empty result"
    result is Failure -> "Call failed!"
    else -> "no match!"
}

我将箭头库用于Try and Option monad。

不幸的是,我只能访问第一个条件“ is Success”的值,而不能访问第二个条件“ is Some”的值。因此,我只能执行“ result.value”,然后获得String的选项。

我想念什么吗?这将为我节省大量的内部“ .map”和“ .fold”调用。

更新

我需要先投射它,这很丑:

result is Success && result.value is Some -> (result.value as Some<String>).t

2 个答案:

答案 0 :(得分:2)

我使用Kotlin 1.3.21在IntelliJ中尝试了您的示例。 它显示了问题的原因: enter image description here

您需要将result.value提取为变量以使其起作用。我找到了以下代码片段来解决它


val result: Try<Option<String>> = Success(Some("test"))

val test = when (result) {
    is Success -> when(val value = result.value) {
        is Some -> value.t
        is None -> "None"
    }
    is Failure -> "Call failed!"
    else -> "no match!"
}

我将Kotlin 1.3.x when用于声明语法。

您还可以使用Arrow API获得类似的结果:

val test = result.fold(
    ifSuccess = { it.getOrElse { "None" }},
    ifFailure = { "Call failed!" }
)

这里您不需要在else中使用when子句。

答案 1 :(得分:0)

您可以像这样简化模式匹配:

val test = result
  .map { it.getOrElse { "Empty result"} }
  .getOrElse { "Call failed!" }

其中有些较为详尽,不需要else替代方式

或者,如果您不关心抛出的异常,则可以在toOption上使用Try

val test = result
  .toOption()
  .getOrElse { "No value!!" }

但是,这显然会丢失一些信息。

我个人会将Try实例冒充给消费者,结果将内部Option.map合并,以使最终结果为Try<String>类型,并且让消费者处理错误。

但是,这取决于问题的很多实际情况。