如何压扁析取类型

时间:2014-09-22 23:36:10

标签: scala scalaz

如果我有以下方法

 def getMyList :\/[Throwable,List[\/[Throwable,Int]]] ={
 ....
 }

如何将getMyList的类型展平为\/[Throwable,List[Int]]

4 个答案:

答案 0 :(得分:9)

只是flatMapsequenceU,它们都在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

,可能有办法实现这一目标