如果我有以下方法
def getMyList :\/[Throwable,List[\/[Throwable,Int]]] ={
....
}
如何将getMyList
的类型展平为\/[Throwable,List[Int]]
答案 0 :(得分:9)
只是flatMap
和sequenceU
,它们都在scalaz中:
def flatten(e: \/[Throwable,List[\/[Throwable,Int]]]): \/[Throwable,List[Int]] = {
e.flatMap(a => a.sequenceU)
}
答案 1 :(得分:1)
如果展平,则表示从List[\/[Throwable,Int]]
中删除左侧类型,然后您可以map
外部分离,collect
正确类型:
list.map(_.collect{ case \/-(x) => x})
答案 2 :(得分:0)
我不认为某些更高的订单会让事情变得平淡无奇。存在/。看起来像Validateion& ValidationNEL将是解决此问题的更好选择。然而,这里是"脏"对于/的解决方案,它将首先返回失败。如果你想积累失败验证是可行的方式
val getMyList: \/[Throwable,List[\/[Throwable,Int]]] =
//\/-(List(-\/(new RuntimeException("test")), \/-(1)))
\/-(List(\/-(2), \/-(1)))
val flatten = getMyList.fold(\/.left, _.foldLeft(\/.right[Throwable, List[Int]](List.empty[Int])) {
case (\/-(list), \/-(i)) => \/-(list :+ i)
case (\/-(list), -\/(err)) => -\/(err)
case (-\/(err), _) => -\/(err)
})
println(flatten)
答案 3 :(得分:0)
我们使用以下方法,其中.sSuccess创建一个\/[_, Seq[T]]
,而.sFail创建一个\/[Throwable, _]
,其中连接了所有throwable的错误消息:
implicit class CondenseEither[T](seq: Seq[\/[Throwable,T]]) = {
def condenseSeq: \/[Throwable, Seq[T]] = {
val errs = seq.filter(_.isLeft).map(_.toEither)
if(errs.isEmpty) seq.map(_.toEither).map(_.right.get).sSuccess
else errs.map(_.left.get.getMessage).mkString(", ")).sFail
}
}
如果没有toEither
s