котлин когда выражение автопередача - PullRequest
0 голосов
/ 14 февраля 2019

Мне бы хотелось, чтобы работал следующий код 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.

К сожалению, я могу получить доступ только к значениюпервое условие «есть успех», а не второе условие «это кто-то».Таким образом, я могу сделать только «result.value», тогда я получу опцию String.

Я что-то упустил?Это сэкономит мне много внутренних вызовов ".map" и ".fold".

Обновление:

Сначала мне нужно разыграть его, что ужасно:

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

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

Я попробовал ваш пример в IntelliJ с Kotlin 1.3.21.Она показывает причину проблемы: 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.

0 голосов
/ 14 февраля 2019

Вы можете упростить сопоставление с шаблоном следующим образом:

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> и позволяет потребителю обработать ошибку.

Однако это зависитмного фактического контекста проблемы.

...