Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何展平析取类型_Scala_Scalaz - Fatal编程技术网

Scala 如何展平析取类型

Scala 如何展平析取类型,scala,scalaz,Scala,Scalaz,如果我有以下方法 def getMyList :\/[Throwable,List[\/[Throwable,Int]]] ={ .... } 如何将getMyList的类型展平到\/[Throwable,List[Int]]如果通过展平,您的意思是从列表[\/[Throwable,Int]]]中删除左侧类型,那么您可以映射外部析取,并收集右侧类型: list.map(_.collect{ case \/-(x) => x}) 我不认为对/存在更高阶的“扁平化”。看起来Valid

如果我有以下方法

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

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

如果通过展平,您的意思是从
列表[\/[Throwable,Int]]]
中删除左侧类型,那么您可以
映射外部析取,并
收集右侧类型:

list.map(_.collect{ case \/-(x) => x})

我不认为对/存在更高阶的“扁平化”。看起来Validateion和ValidationNEL将是解决此问题的更好选择。然而,这里是/的“脏”解决方案,它将首先返回fail。若你们想积累失败,验证是一条路要走

 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)

我们使用以下方法,其中.ssaccess创建一个
\/[\uu,Seq[T]]
,.sFail创建一个
\/[Throwable,\u]
,并将所有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

只需
flatMap
sequenceU
,它都在scalaz中:

  def flatten(e: \/[Throwable,List[\/[Throwable,Int]]]): \/[Throwable,List[Int]] = {
    e.flatMap(a => a.sequenceU)
  }

回答得好,你能简单解释一下
sequenceU
。我尝试使用普通的
序列
,但失败。@bmaderbacher
sequenceU
自动为
应用程序
实例推断正确的类型构造函数。这里有一篇关于这个主题的文章值得一读:@GabrielePetronella说了什么:)@GabrielePetronella谢谢你的解释。来自Haskell Scala的类型推断,有时真的很烦人。您可能还想看看traverseU作为sequenceU的潜在替代品,以便在前面获得
\/[Throwable,List[Int]]
。请参阅
BindSyntax
-中的
连接
。这提供了
join
,对于具有
Bind[A]
的所有类型
A
,它本质上是
flatten
的同义词。