如果我有以下方法如何扁平化脱节型
def getMyList :\/[Throwable,List[\/[Throwable,Int]]] ={
....
}
如何扁平化的getMyList
类型\/[Throwable,List[Int]]
如果我有以下方法如何扁平化脱节型
def getMyList :\/[Throwable,List[\/[Throwable,Int]]] ={
....
}
如何扁平化的getMyList
类型\/[Throwable,List[Int]]
只是flatMap
和sequenceU
,这一切都在scalaz:
def flatten(e: \/[Throwable,List[\/[Throwable,Int]]]): \/[Throwable,List[Int]] = {
e.flatMap(a => a.sequenceU)
}
如果扁平化,您的意思是List[\/[Throwable,Int]]
拆下左类型,那么你就可以map
外部析取和collect
正确的类型:
list.map(_.collect{ case \/-(x) => x})
我不认为一些更高的顺序“扁平”存在于/。看起来像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)
请参阅'BindSyntax'中的'join' - https://github.com/scalaz/scalaz/blob/series/7.1.x/core/src/main/scala/scalaz/syntax/BindSyntax.scala# L15。这提供了'join',它与具有'Bind [A]'的所有类型'A'的'flatten'基本同义。 – drstevens 2014-09-23 14:49:58
我们用下面的方法,其中.sSuccess创建一个\/[_, Seq[T]]
和.sFail创建包含所有可抛出错误消息级联一个\/[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
小号
很好的答案,你可以简单解释一下'sequenceU'。我用普通的“序列”尝试,但失败了。 – bmaderbacher 2014-09-23 00:21:42
@bmaderbacher'sequenceU'自动推断'Applicative'实例的正确类型构造函数。这里有一篇值得阅读的文章:http://eed3si9n.com/learning-scalaz-day15 – 2014-09-23 00:23:32
什么@GabrielePetronella说:) – Noah 2014-09-23 00:27:26