我希望以下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
答案 0 :(得分:2)
我使用Kotlin 1.3.21在IntelliJ中尝试了您的示例。 它显示了问题的原因:
您需要将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>
类型,并且让消费者处理错误。
但是,这取决于问题的很多实际情况。