Kotlin箭头将失败列表转换为失败列表

时间:2019-05-22 14:16:00

标签: kotlin arrow-kt

如何转换以下内容:

List<Try<String>>

收件人:

Try<List<String>>

使用kotlin和功能库箭头(0.8.2)。我想将其包装在一个自定义异常中。哪一个“字符串”失败都没关系。

更新

因为下面的答案就足够了,但是我发现它很难阅读。因此,我实现了以下内容:

创建以下功能:

    fun getFailedStrings(result: List<Try<String>>): List<Failure> {
return result.fold(
    initial = listOf(),
    operation = { accumulator, nextUpdate ->
        nextUpdate.fold(
            ifSuccess = { accumulator },
            ifFailure = { accumulator + Failure(it) }
        )
    })

}

然后使用函数的结果:

  return if (failedStrings.isNotEmpty()) {
      failedStrings.first() // or whatever fits your usecase
  } else {
     // strings is the initial result of List<Try<String>>
      Success(strings.mapNotNull { it.orNull() })
   }

2 个答案:

答案 0 :(得分:2)

如果我们不关心保留原始异常,则可以通过遍历执行以下操作:

val traversedTries = tries.traverse(Try.applicative(), ::identity)

这将返回一个类型为Try<ListK<String>>的实例,其中包含所有字符串或找到的第一个异常。

ListKList的扩展,但是如果需要将其设为.map { it as List<String> },我们可以选择在最后添加Try<List<String>>来投射它。

或者,如果我们想将成功和失败分开,我们可以创建以下函数:

fun <A> List<Try<A>>.splitSuccessFailure() : Tuple2<List<A>, List<Throwable>> =
  fold(emptyList<A>() toT emptyList<Throwable>()) { (successes, failures), it -> 
    it.fold({ successes toT (failures + it) }, { (successes + it) toT failures })  
  }

然后,当我们要使用它时,我们可以执行以下操作:

val (successes, failures) = invalidTries.splitSuccessFailure()

给我们两个列表,分别列出成功值和失败。

答案 1 :(得分:1)

这似乎可行:

 fun convert(input: List<Try<String>>): Try<List<String>> =
    input.fold(Try.just(emptyList())) { acc, i ->
        acc.flatMap { list ->
            i.flatMap {
                Try.just(list + it)
            }
        }
    }